Início › Blog › Firebase Security Rules

Firebase Security Rules: 7 erros que vazam seu banco inteiro

12 de outubro de 2026 · ~7 min de leitura

As Firebase Security Rules são a única coisa entre o seu banco de dados e a internet. Quando você constrói um SaaS rápido — ainda mais com ajuda de IA — é exatamente a camada que costuma ficar para depois. Abaixo, os 7 erros que mais vemos em auditorias, cada um com o código errado, o código certo e por que importa.

Por que isso é sério: ao contrário de um bug de back-end, uma regra aberta não dá erro — ela funciona lindamente. O vazamento só aparece quando alguém abre o DevTools, copia a config do Firebase (que é pública por design) e consulta o seu banco direto, sem passar pelo seu app.

1. A regra de modo de teste que ficou em produção

Todo projeto Firebase nasce com uma regra temporária. É o erro número um porque é literalmente o padrão, e ninguém lembra de voltar.

// ❌ Qualquer pessoa na internet lê e escreve tudo
match /{document=**} {
  allow read, write: if true;
}

Uma variação mais sutil usa uma data de expiração que já passou (request.time < timestamp.date(2026, 1, 1)) — depois do prazo a regra nega tudo, e aí alguém "conserta" trocando por if true. A correção é nunca deixar if true em coleção com dado real: toda leitura e escrita precisa de uma condição explícita.

2. Confundir "está logado" com "é o dono"

Este é o vazamento clássico de SaaS multi-cliente. A regra checa apenas se existe um usuário autenticado — então qualquer cliente logado lê os dados de todos os outros.

// ❌ Todo usuário logado lê qualquer pedido
match /orders/{id} {
  allow read: if request.auth != null;
}

// ✅ Só o dono do documento lê
match /orders/{id} {
  allow read: if request.auth != null
    && resource.data.ownerId == request.auth.uid;
}

Em OWASP isso é um IDOR/BOLA (Broken Object Level Authorization) — e é a falha de autorização mais comum em APIs. Toda coleção com dado por cliente precisa amarrar o documento ao request.auth.uid (ou ao tenant/clinicId do usuário). É o tema do nosso guia sobre isolamento multi-cliente.

3. Confiar num campo que o cliente controla

Dá para escrever uma regra que parece segura, mas lê o papel do usuário de um lugar que o próprio usuário pode alterar:

// ❌ "role" vem do documento que o usuário escreve
allow write: if request.resource.data.role == 'admin';

// ✅ "admin" vem do token de auth (custom claims), imutável pelo cliente
allow write: if request.auth.token.admin == true;

Permissões têm que vir de uma fonte que o cliente não consegue forjar: custom claims no token, ou um documento que só o back-end escreve. Nunca de um campo que entra no mesmo write que a regra deveria proteger.

4. Não validar o que está sendo escrito

Regras não servem só para dizer "pode ou não pode" — elas são o seu validador de integridade no banco. Sem validação, um cliente pode gravar um saldo negativo, um plano "enterprise" que não pagou, ou inflar um campo de uso.

// ✅ Valida formato, tamanho e campos imutáveis
match /profiles/{uid} {
  allow update: if request.auth.uid == uid
    && request.resource.data.plan == resource.data.plan   // não troca o próprio plano
    && request.resource.data.email is string
    && request.resource.data.name.size() < 120;
}

5. O wildcard recursivo que abre tudo abaixo

O {document=**} casa com a coleção e todas as subcoleções. Uma regra permissiva no nível errado vaza tudo que está aninhado dentro.

// ❌ Libera a subcoleção /users/{uid}/private também
match /users/{uid}/{document=**} {
  allow read: if request.auth != null;
}

Lembre-se: regras não cascateiam de cima para baixo (uma regra em /users não protege /users/x/cards), mas o =** casca para baixo. Seja explícito em cada nível.

6. Proteger o Firestore e esquecer o Storage

Firestore, Realtime Database e Cloud Storage têm conjuntos de regras separados. É comum caprichar no Firestore e deixar o Storage no padrão aberto — e os uploads dos usuários (documentos, comprovantes, fotos) ficam públicos para quem tiver a URL.

// storage.rules — ✅ cada usuário só mexe na própria pasta
match /uploads/{uid}/{file} {
  allow read, write: if request.auth != null
    && request.auth.uid == uid;
}

7. Achar que as Rules substituem o back-end

Security Rules protegem o acesso ao banco, mas não fazem rate limit, não verificam assinatura de webhook, não param um bot e não validam lógica de negócio complexa. Para o resto você ainda precisa de App Check (garante que a chamada vem do seu app), de Cloud Functions para operações sensíveis, e de validação no servidor. As Rules são uma camada, não a muralha inteira.

Como auditar as suas regras hoje: rode o emulador do Firebase com testes que tentam ler o documento de outro usuário; use o Rules Playground no console para simular um get sem auth; e procure por qualquer if true, request.auth != null solto (sem checagem de dono) e {document=**} nos seus arquivos de regras.

Não quer caçar isso à mão?

O SAAS SHIELD faz uma revisão de segurança do seu repositório React/Next.js com Firebase ou Supabase e devolve cada falha com local, evidência e correção.

Solicitar auditoria →