Evite regras inseguras

Use este guia para entender vulnerabilidades comuns nas configurações das regras de segurança do Firebase, revisar e proteger melhor suas próprias regras e testar suas alterações antes de implantá-las.

Se você receber um alerta de que seus dados não estão devidamente protegidos, revise esses erros comumente cometidos e atualize quaisquer regras vulneráveis.

Acesse suas regras de segurança do Firebase

Para visualizar suas regras existentes, use a CLI do Firebase ou o console do Firebase. Certifique-se de editar suas regras usando o mesmo método, de forma consistente, para evitar substituir atualizações por engano. Se você não tiver certeza se suas regras definidas localmente refletem as atualizações mais recentes, o Console do Firebase sempre mostrará a versão implantada mais recentemente das suas regras de segurança do Firebase.

Para acessar suas regras no console do Firebase , selecione seu projeto e navegue até Realtime Database , Cloud Firestore ou Storage . Clique em Regras quando estiver no banco de dados ou bucket de armazenamento correto.

Para acessar suas regras na CLI do Firebase, acesse o arquivo de regras anotado em seu arquivo firebase.json .

Entenda as regras de segurança do Firebase

As regras de segurança do Firebase protegem seus dados contra usuários mal-intencionados. Ao criar uma instância de banco de dados ou bucket do Cloud Storage no Console do Firebase, você pode optar por negar acesso a todos os usuários ( modo bloqueado ) ou conceder acesso a todos os usuários ( modo de teste ). Embora você possa querer uma configuração mais aberta durante o desenvolvimento, reserve um tempo para configurar adequadamente suas regras e proteger seus dados antes de implantar seu aplicativo.

Ao desenvolver seu aplicativo e testar configurações diferentes para suas regras, use um dos emuladores locais do Firebase para executar seu aplicativo em um ambiente de desenvolvimento local.

Cenários comuns com regras inseguras

As regras que você pode ter configurado por padrão ou conforme trabalhou inicialmente no desenvolvimento de seu aplicativo devem ser revisadas e atualizadas antes de implantar seu aplicativo. Certifique-se de proteger adequadamente os dados dos seus usuários, evitando as seguintes armadilhas comuns.

Acesso livre

Ao configurar seu projeto do Firebase, você pode ter definido suas regras para permitir acesso aberto durante o desenvolvimento. Você pode pensar que é a única pessoa que usa seu aplicativo, mas se o tiver implantado, ele estará disponível na Internet. Se você não estiver autenticando usuários e configurando regras de segurança, qualquer pessoa que adivinhar o ID do seu projeto poderá roubar, modificar ou excluir os dados.

Não recomendado: acesso de leitura e gravação para todos os usuários.
// 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 via 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;
   
}
 
}
}
   
Solução: Regras que restringem o acesso de leitura e gravação.

Crie regras que façam sentido para sua hierarquia de dados. Uma das soluções comuns para essa insegurança é a segurança baseada no usuário com Firebase Authentication. Saiba mais sobre como autenticar usuários com regras .

service cloud.firestore {
  match
/databases/{database}/documents {
   
// Allow only authenticated content owners access
    match
/some_collection/{document} {
      allow read
, write: if request.auth != null && request.auth.uid == request.resource.data.author_uid
   
}
 
}
}
 
service 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 != null && request.auth.uid == request.resource.data.author_uid
   
}
 
}
}
 
{
 
"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"
     
}
   
}
 
}
}
   
{
 
// 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"
   
}
 
}
}
   
// Grants a user access to a node matching their user ID
service firebase
.storage {
  match
/b/{bucket}/o {
   
// Files look like: "user/<UID>/path/to/file.txt"
    match
/user/{userId}/{allPaths=**} {
      allow read
, write: if request.auth.uid == userId;
   
}
 
}
}
service firebase.storage {
  match
/b/{bucket}/o {
   
// Files look like: "user/<UID>/path/to/file.txt"
    match
/user/{userId}/{allPaths=**} {
      allow read
;
      allow write
: if request.auth.uid == userId;
   
}
 
}
}
 

Acesso para qualquer usuário autenticado

Às vezes, as regras verificam se um usuário está conectado, mas não restringem ainda mais o acesso com base nessa autenticação. Se uma de suas regras incluir auth != null , confirme se deseja que qualquer usuário conectado tenha acesso aos dados.

Não recomendado: qualquer usuário conectado terá acesso de leitura e gravação em todo o seu banco de dados.
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;
   
}
 
}
}
Solução: Acesso restrito utilizando condições de segurança.

Ao verificar a autenticação, você também pode querer usar uma das propriedades de autenticação para restringir ainda mais o acesso a usuários específicos para conjuntos de dados específicos. Saiba mais sobre as diferentes propriedades de autenticação .

service 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.
   
}
 
}
}
// 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 "admin" attribute set
// to "true" grants write access to data

service cloud
.firestore {
  match
/databases/{database}/documents {
    match
/collection/{document} {
      allow write
: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true;
      allow read
: true;
   
}
 
}
}
 
service 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
   
}
 
}
}
 
{
 
"rules": {
   
"some_path": {
     
"$uid": {
       
// Allow only authenticated content owners access to their data
       
".read": "auth.uid === $uid",
       
".write": "auth.uid === $uid"
     
}
   
}
 
}
}
   
{
 
"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"
     
}
   
}
 
}
}
   
{
 
// 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"
   
}
 
}
}
   
// Allow reads if the group ID in your token matches the file metadata's `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;
}
// Grants a user access to a node matching their user ID
service firebase
.storage {
  match
/b/{bucket}/o {
   
// Files look like: "user/<UID>/path/to/file.txt"
    match
/user/{userId}/{allPaths=**} {
      allow read
, write: if request.auth.uid == userId;
   
}
 
}
}
service firebase.storage {
  match
/b/{bucket}/o {
   
// Files look like: "user/<UID>/path/to/file.txt"
    match
/user/{userId}/{allPaths=**} {
      allow read
;
      allow write
: if request.auth.uid == userId;
   
}
 
}
}
 

(Realtime Database) Regras herdadas incorretamente

Regras de segurança de banco de dados em tempo real em cascata, com regras em caminhos pais mais superficiais substituindo regras em nós filhos mais profundos. Ao escrever uma regra em um nó filho, lembre-se de que ela só pode conceder privilégios adicionais. Você não pode refinar ou revogar o acesso aos dados em um caminho mais profundo no seu banco de dados.

Não recomendado: Refinando regras em caminhos filhos
{
 
"rules": {
     
"foo": {
       
// allows read to /foo/*
       
".read": "data.child('baz').val() === true",
       
"bar": {
         
/* ignored, since read was allowed already */
         
".read": false
       
}
     
}
 
}
}
Solução: escreva regras amplas em caminhos pai e conceda privilégios mais específicos em caminhos filho. Se suas necessidades de acesso a dados exigirem mais granularidade, mantenha suas regras granulares. Saiba mais sobre regras de segurança do Realtime Database em cascata na sintaxe principal das regras de segurança do Realtime Database .

Acesso fechado

Enquanto você desenvolve seu aplicativo, outra abordagem comum é manter seus dados bloqueados. Normalmente, isso significa que você fechou o acesso de leitura e gravação a todos os usuários, da seguinte maneira:

// 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;
   
}
 
}
}

Os SDKs Admin do Firebase e o Cloud Functions ainda podem acessar seu banco de dados. Use essas regras quando pretender usar o Cloud Firestore ou o Realtime Database como back-end somente de servidor em conjunto com o SDK Admin do Firebase. Embora seja seguro, você deve testar se os clientes do seu aplicativo podem recuperar dados corretamente.

Saiba mais sobre as regras de segurança do Cloud Firestore e como elas funcionam em Primeiros passos com as regras de segurança do Cloud Firestore .

Teste suas regras de segurança do Cloud Firestore

Para verificar o comportamento do seu aplicativo e as configurações das regras de segurança do Cloud Firestore, use o Firebase Emulator . Use o emulador do Cloud Firestore para executar e automatizar testes de unidade em um ambiente local antes de implantar qualquer alteração.

Para validar rapidamente as regras de segurança do Firebase no console do Firebase, use o Simulador de regras do Firebase .