Utilisez ce guide pour comprendre les failles courantes des configurations Firebase Security Rules, examiner et mieux sécuriser vos propres règles, et tester vos modifications avant de les déployer.
Si vous recevez une alerte indiquant que vos données ne sont pas correctement sécurisées, examinez ces erreurs courantes et mettez à jour les règles vulnérables.
Accéder à votre Firebase Security Rules
Pour afficher votre Rules existante, utilisez la CLI Firebase ou la console Firebase. Veillez à modifier vos règles de manière cohérente, en utilisant la même méthode, pour éviter d'écraser par erreur les mises à jour. Si vous ne savez pas si vos règles définies localement reflètent les mises à jour les plus récentes, la console Firebase affiche toujours la version la plus récente de votre Firebase Security Rules.
Pour accéder à vos règles depuis la console Firebase, sélectionnez votre projet, puis accédez à Realtime Database, Cloud Firestore ou Stockage. Une fois que vous êtes dans la base de données ou le bucket de stockage appropriés, cliquez sur Rules (Règles).
Pour accéder à vos règles à partir de la CLI Firebase, accédez au fichier de règles spécifié dans votre fichier firebase.json.
Comprendre Firebase Security Rules
Firebase Security Rules protège vos données contre les utilisateurs malveillants. Lorsque vous créez une instance de base de données ou un bucket Cloud Storage dans la console Firebase, vous pouvez choisir de refuser l'accès à tous les utilisateurs (mode verrouillé) ou d'accorder l'accès à tous les utilisateurs (mode test). Bien que vous souhaitiez peut-être une configuration plus ouverte pendant le développement, prenez le temps de configurer correctement vos règles et de sécuriser vos données avant de déployer votre application.
Lorsque vous développez votre application et testez différentes configurations pour vos règles, utilisez l'un des émulateurs Firebase locaux pour exécuter votre application dans un environnement de développement local.
Scénarios courants utilisant des règles non sécurisées
Les Rules que vous avez configurées par défaut ou que vous avez initialement développées avec votre application doivent être vérifiées et mises à jour avant de déployer votre application. Assurez-vous de sécuriser correctement les données de vos utilisateurs en évitant les problèmes courants suivants.
Libre accès
Lors de la configuration de votre projet Firebase, vous avez peut-être défini des règles autorisant le libre accès lors du développement. Vous pensez peut-être que vous êtes la seule personne à utiliser votre application, mais si vous l'avez déployée, elle est disponible sur Internet. Si vous n'authentifiez pas les utilisateurs et ne configurez pas les règles de sécurité, toute personne qui devine l'ID de votre projet peut voler, modifier ou supprimer les données.
Scénario non recommandé:accès en lecture et en écriture pour tous les utilisateurs.
// Allow read/write access to all users under any conditions // Warning: **NEVER** use this ruleset in production; it allows // anyone to overwrite your entire database. service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if true; } } } { // Allow read/write access to all users under any conditions // Warning: **NEVER** use this ruleset in production; it allows // anyone to overwrite your entire database. "rules": { ".read": true, ".write": true } } // Anyone can read or write to the bucket, even non-users of your app. // Because it is shared with App Engine, this will also make // files uploaded using App Engine public. // Warning: This rule makes every file in your Cloud Storage bucket accessible to any user. // Apply caution before using it in production, since it means anyone // can overwrite all your files. service firebase.storage { match /b/{bucket}/o { match /{allPaths=**} { allow read, write; } } } |
Solution : règles limitant l'accès en lecture et en écriture. Créez des règles adaptées à la hiérarchie de vos données. L'une des solutions courantes pour remédier à ce scénario non sécurisé consiste à appliquer une sécurité basée sur l'utilisateur à l'aide de Firebase Authentication. En savoir plus sur l'authentification des utilisateurs à l'aide de règles Propriétaire de contenu uniquementservice cloud.firestore { match /databases/{database}/documents { // Allow only authenticated content owners access match /some_collection/{document} { // Allow reads and deletion if the current user owns the existing document allow read, delete: if request.auth.uid == resource.data.author_uid; // Allow creation if the current user owns the new document allow create: if request.auth.uid == request.resource.data.author_uid; // Allow updates by the owner, and prevent change of ownership allow update: if request.auth.uid == request.resource.data.author_uid && request.auth.uid == resource.data.author_uid; } } } Accès public et privé mixteservice cloud.firestore { match /databases/{database}/documents { // Allow public read access, but only content owners can write match /some_collection/{document} { // Allow public reads allow read: if true // Allow creation if the current user owns the new document allow create: if request.auth.uid == request.resource.data.author_uid; // Allow updates by the owner, and prevent change of ownership allow update: if request.auth.uid == request.resource.data.author_uid && request.auth.uid == resource.data.author_uid; // Allow deletion if the current user owns the existing document allow delete: if request.auth.uid == resource.data.author_uid; } } } Propriétaire de contenu uniquement{ "rules": { "some_path": { "$uid": { // Allow only authenticated content owners access to their data ".read": "auth !== null && auth.uid === $uid", ".write": "auth !== null && auth.uid === $uid" } } } } Accès public et privé mixte{ // Allow anyone to read data, but only authenticated content owners can // make changes to their data "rules": { "some_path/$uid": { ".read": true, // or ".read": "auth.uid !== null" for only authenticated users ".write": "auth.uid === $uid" } } } Propriétaire de contenu uniquement// Grants a user access to a node matching their user ID service firebase.storage { match /b/{bucket}/o { // Files look like: "user/<UID>/file.txt" match /user/{userId}/{fileName} { allow read, write: if request.auth.uid == userId; } } } Accès public et privé mixteservice firebase.storage { match /b/{bucket}/o { // Files look like: "user/<UID>/file.txt" match /user/{userId}/{fileName} { allow read; allow write: if request.auth.uid == userId; } } } |
Accès pour tout utilisateur authentifié
Parfois, Rules vérifie qu'un utilisateur est connecté, mais ne limite pas pour autant l'accès en fonction de cette authentification. Si l'une de vos règles inclut auth != null
, confirmez que vous souhaitez qu'un utilisateur connecté ait accès aux données.
Scénario non recommandé:tout utilisateur connecté dispose d'un accès en lecture et en écriture à l'ensemble de votre base de données.
service cloud.firestore { match /databases/{database}/documents { match /some_collection/{document} { allow read, write: if request.auth.uid != null; } } } { "rules": { ".read": "auth.uid !== null", ".write": "auth.uid !== null" } } // Only authenticated users can read or write to the bucket service firebase.storage { match /b/{bucket}/o { match /{allPaths=**} { allow read, write: if request.auth != null; } } } |
Solution : limitez l'accès à l'aide de conditions de sécurité. Lorsque vous vérifiez l'authentification, vous pouvez également utiliser l'une des propriétés d'authentification pour limiter davantage l'accès d'utilisateurs spécifiques à des ensembles de données spécifiques. En savoir plus sur les différentes propriétés d'authentification Accès basé sur des rôlesservice cloud.firestore { match /databases/{database}/documents { // Assign roles to all users and refine access based on user roles match /some_collection/{document} { allow read: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Reader" allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Writer" // Note: Checking for roles in your database using `get` (as in the code // above) or `exists` carry standard charges for read operations. } } } Accès basé sur des attributs// Give each user in your database a particular attribute // and set it to true/false // Then, use that attribute to grant access to subsets of data // For example, an "administrator" attribute set // to "true" grants write access to data service cloud.firestore { match /databases/{database}/documents { match /some_collection/{document} { allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true; allow read: true; } } } Accès public et privé mixteservice cloud.firestore { match /databases/{database}/documents { // Allow public read access, but only content owners can write match /some_collection/{document} { allow read: if true allow write: if request.auth.uid == request.resource.data.author_uid } } } Propriétaire de contenu uniquement{ "rules": { "some_path": { "$uid": { // Allow only authenticated content owners access to their data ".read": "auth.uid === $uid", ".write": "auth.uid === $uid" } } } } Accès délimité par chemin d'accès{ "rules": { "some_path/$uid": { ".write": "auth.uid === $uid", // Create a "public" subpath in your dataset "public": { ".read": true // or ".read": "auth.uid !== null" }, // Create a "private" subpath in your dataset "private": { ".read": "auth.uid === $uid" } } } } Accès public et privé mixte{ // Allow anyone to read data, but only authenticated content owners can // make changes to their data "rules": { "some_path/$uid": { ".read": true, // or ".read": "auth.uid !== null" for only authenticated users ".write": "auth.uid === $uid" } } } Accès basé sur les groupes// Allow reads if the group ID in your token matches the file metadata `owner` property // Allow writes if the group ID is in the user's custom token match /files/{groupId}/{fileName} { allow read: if resource.metadata.owner == request.auth.token.groupId; allow write: if request.auth.token.groupId == groupId; } Propriétaire de contenu uniquement// Grants a user access to a node matching their user ID service firebase.storage { match /b/{bucket}/o { // Files look like: "user/<UID>/file.txt" match /user/{userId}/{fileName} { allow read, write: if request.auth.uid == userId; } } } Accès public et privé mixteservice firebase.storage { match /b/{bucket}/o { // Files look like: "user/<UID>/file.txt" match /user/{userId}/{fileName} { allow read; allow write: if request.auth.uid == userId; } } } |
(Realtime Database) Règles héritées de manière incorrecte
Cascade Realtime Database Security Rules, avec des règles plus superficielles, les chemins parent remplaçant les règles dans les nœuds enfants plus profonds. Lorsque vous écrivez une règle à un nœud enfant, n'oubliez pas qu'elle ne peut accorder que des droits supplémentaires. Vous ne pouvez pas affiner ni révoquer l'accès aux données à un niveau plus profond de votre base de données.
Non recommandé:affiner les règles au niveau des chemins d'accès enfants
{ "rules": { "foo": { // allows read to /foo/* ".read": "data.child('baz').val() === true", "bar": { /* ignored, since read was allowed already */ ".read": false } } } } |
Solution:Écrivez des règles à des chemins parent larges et accordez des droits plus spécifiques aux chemins enfants. Si vos besoins d'accès aux données nécessitent plus de précision, conservez vos règles précises. En savoir plus sur la cascade Realtime Database Security Rules dans la syntaxe de base de Realtime Database Security Rules |
Accès fermé
Lorsque vous développez votre application, une autre méthode courante consiste à verrouiller vos données. En général, cela signifie que vous avez désactivé l'accès en lecture et en écriture pour tous les utilisateurs, comme suit :
// Deny read/write access to all users under any conditions service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if false; } } }
{ "rules": { ".read": false, ".write": false } }
// Access to files through Cloud Storage is completely disallowed. // Files may still be accessible through App Engine or Google Cloud Storage APIs. service firebase.storage { match /b/{bucket}/o { match /{allPaths=**} { allow read, write: if false; } } }
Les SDK Admin Firebase et Cloud Functions peuvent toujours accéder à votre base de données. Appliquez ces règles lorsque vous envisagez d'utiliser Cloud Firestore ou Realtime Database en tant que backend serveur uniquement conjointement avec le SDK Admin Firebase. Bien qu'il soit sécurisé, vous devez vérifier que les clients de votre application peuvent récupérer correctement les données.
Pour en savoir plus sur Cloud Firestore Security Rules et son fonctionnement, consultez la section Premiers pas avec Cloud Firestore Security Rules.
Tester votre Cloud Firestore Security Rules
Pour vérifier le comportement de votre application et vérifier la configuration de vos Cloud Firestore Security Rules, utilisez l'émulateur Firebase. Utilisez l'émulateur Cloud Firestore pour exécuter et automatiser des tests unitaires dans un environnement local avant de déployer des modifications.
Pour valider rapidement Firebase Security Rules dans la console Firebase, utilisez le simulateur de règles Firebase.