Utilizza questa guida per comprendere le vulnerabilità comuni nelle configurazioni Firebase Security Rules, esaminare e proteggere meglio le tue regole e testare le modifiche prima di implementarle.
Se ricevi un avviso che ti informa che i tuoi dati non sono protetti correttamente, esamina questi errori comuni e aggiorna le regole vulnerabili.
Accedere a Firebase Security Rules
Per visualizzare i tuoi Rules esistenti, utilizza l'interfaccia a riga di comando Firebase o la console Firebase. Assicurati di modificare le regole utilizzando sempre lo stesso metodo per evitare di sovrascrivere per errore gli aggiornamenti. Se non sai con certezza se le regole definite localmente riflettono gli aggiornamenti più recenti, la Console Firebase mostra sempre la versione di Firebase Security Rules di cui è stato eseguito il deployment più di recente.
Per accedere alle regole dalla console Firebase, seleziona il progetto, quindi vai a Realtime Database, Cloud Firestore o Storage. Fai clic su Regole dopo aver selezionato il database o il bucket di archiviazione corretto.
Per accedere alle regole dall'interfaccia a riga di comando Firebase, vai al file delle regole indicato nel file firebase.json.
Informazioni su Firebase Security Rules
Firebase Security Rules proteggi i tuoi dati da utenti malintenzionati. Quando crei un'istanza di database o un bucket Cloud Storage nella console Firebase, puoi scegliere di negare l'accesso a tutti gli utenti (Modalità bloccata) o concedere l'accesso a tutti gli utenti (Modalità di test). Anche se potresti preferire una configurazione più aperta durante lo sviluppo, assicurati di dedicare il tempo necessario per configurare correttamente le regole e mettere al sicuro i dati prima di implementare l'app.
Mentre sviluppi l'app e testi diverse configurazioni per le regole, utilizza uno degli emulatori Firebase locali per eseguire l'app in un ambiente di sviluppo locale.
Scenari comuni con regole non sicure
Il Rules che potresti aver configurato per impostazione predefinita o durante lo sviluppo iniziale della tua app deve essere esaminato e aggiornato prima di eseguire il deployment dell'app. Assicurati di proteggere adeguatamente i dati degli utenti evitando i seguenti errori comuni.
Accesso libero
Durante la configurazione del progetto Firebase, potresti aver impostato le regole per consentire l'accesso aperto durante lo sviluppo. Potresti pensare di essere l'unica persona che utilizza la tua app, ma se l'hai implementata, è disponibile su internet. Se non autentichi gli utenti e non configuri regole di sicurezza, chiunque indovini il tuo ID progetto può rubare, modificare o eliminare i dati.
Non consigliato:accesso in lettura e scrittura per tutti gli utenti.
// 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; } } } |
Soluzione: regole che limitano l'accesso in lettura e scrittura.
Crea regole che abbiano senso per la gerarchia dei dati. Una delle soluzioni comuni a questo problema è la sicurezza basata sugli utenti con Firebase Authentication. Scopri di più sull'autenticazione degli utenti con le regole. Solo proprietario dei contenutiservice 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; } } } Accesso misto pubblico e privatoservice 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; } } } Solo proprietario dei contenuti{ "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" } } } } Accesso misto pubblico e privato{ // 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" } } } Solo proprietario dei contenuti// 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; } } } Accesso misto pubblico e privatoservice 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; } } } |
Accesso per qualsiasi utente autenticato
A volte, Rules verifica che un utente abbia eseguito l'accesso, ma non limita ulteriormente l'accesso in base a quell'autenticazione. Se una delle tue regole include
auth != null
, conferma che vuoi che qualsiasi utente che ha eseguito l'accesso abbia accesso ai
dati.
Non consigliato:qualsiasi utente che ha eseguito l'accesso ha accesso in lettura e scrittura all'intero database.
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; } } } |
Soluzione:limita l'accesso utilizzando le condizioni di sicurezza.
Quando controlli l'autenticazione, ti consigliamo di utilizzare anche una delle proprietà di autenticazione per limitare ulteriormente l'accesso a utenti specifici per set di dati specifici. Scopri di più sulle diverse proprietà di autenticazione. Accesso basato sul ruoloservice 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. } } } Accesso basato su attributi// 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; } } } Accesso misto pubblico e privatoservice 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 } } } Solo proprietario dei contenuti{ "rules": { "some_path": { "$uid": { // Allow only authenticated content owners access to their data ".read": "auth.uid === $uid", ".write": "auth.uid === $uid" } } } } Accesso delimitato dal percorso{ "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" } } } } Accesso misto pubblico e privato{ // 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" } } } Accesso basato su gruppi// 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; } Solo proprietario dei contenuti// 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; } } } Accesso misto pubblico e privatoservice 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) Regole ereditate in modo improprio
Realtime Database Security Rules in cascata, con le regole dei percorsi principali meno approfonditi che sostituiscono le regole dei nodi secondari più profondi. Quando scrivi una regola in un nodo secondario, ricorda che può concedere solo privilegi aggiuntivi. Non puoi perfezionare o revocare l'accesso ai dati in un percorso più approfondito del database.
Sconsigliato: perfezionamento delle regole nei percorsi secondari
{ "rules": { "foo": { // allows read to /foo/* ".read": "data.child('baz').val() === true", "bar": { /* ignored, since read was allowed already */ ".read": false } } } } |
Soluzione: scrivi regole per i percorsi principali che siano generali e concedi privilegi più specifici per i percorsi secondari Se le tue esigenze di accesso ai dati richiedono una maggiore granularità, mantieni le regole granulari. Scopri di più sulla definizione di Realtime Database Security Rules in cascata nella sintassi di base di Realtime Database Security Rules. |
Accesso chiuso
Durante lo sviluppo dell'app, un altro approccio comune è mantenere i dati protetti. In genere, significa che hai bloccato l'accesso in lettura e scrittura per tutti gli utenti, come segue:
// 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; } } }
Gli SDK Firebase Admin e Cloud Functions possono comunque accedere al database. Utilizza queste regole se intendi utilizzare Cloud Firestore o Realtime Database come backend solo per il server in combinazione con l'SDK Firebase Admin. Sebbene sia sicuro, devi verificare che i client della tua app possano recuperare correttamente i dati.
Scopri di più su Cloud Firestore Security Rules e su come funzionano in Guida introduttiva a Cloud Firestore Security Rules.
Testa Cloud Firestore Security Rules
Per controllare il comportamento dell'app e verificare le configurazioni di Cloud Firestore Security Rules, utilizza l'emulatore Firebase. Utilizza l'emulatore Cloud Firestore per eseguire e automatizzare i test di unità in un ambiente locale prima di implementare qualsiasi modifica.
Per convalidare rapidamente Firebase Security Rules nella console Firebase, utilizza il simulatore di regole Firebase.