Seu app feito com IA está vazando dados? Uma verificação de 10 minutos no Supabase
Apps feitos com Lovable ou Bolt no Supabase costumam ir ao ar com tabelas que qualquer um lê. Como verificar o seu em dez minutos e o que corrigir primeiro.
4 min de leitura
Apps feitos com Lovable, Bolt ou ferramentas parecidas normalmente guardam os dados no Supabase. É uma boa escolha: o Supabase é um banco Postgres de verdade, com autenticação embutida. Mas ele vem com uma regra que as ferramentas de IA nem sempre seguem, e, quando ela fica de fora, os dados do app podem ser lidos por qualquer pessoa que abra as ferramentas de desenvolvedor do navegador.
Este guia mostra como verificar o seu próprio app em uns dez minutos, sem instalar nada.
Por que a chave do seu app é pública
Seu app conversa com o Supabase a partir do navegador, então o navegador precisa de uma chave. Essa chave, chamada anon key (ou publishable key nos projetos mais novos), vai dentro do JavaScript do seu app. Qualquer pessoa consegue encontrá-la. Isso é intencional.
O que protege seus dados não é a chave, e sim o Row Level Security (RLS): regras no banco que decidem quais linhas cada visitante pode ler ou alterar. Com o RLS ligado e boas regras, uma chave pública é inofensiva. Com o RLS desligado, a chave pública lê a tabela inteira.
| Situação | O que um estranho com a sua chave pública consegue fazer |
|---|---|
| RLS desligado na tabela | Ler (e muitas vezes alterar) todas as linhas |
| RLS ligado, sem regras | Nada: toda requisição é recusada |
RLS ligado, regra using (true) |
O mesmo que com o RLS desligado, para as ações e os papéis que a regra cobre |
RLS ligado, regra baseada em auth.uid() |
Só as linhas que pertencem ao usuário logado |
Passo 1: liste as tabelas sem RLS
Abra seu projeto no painel do Supabase, vá ao SQL Editor e execute:
select c.relname as table_name,
c.relrowsecurity as rls_enabled
from pg_class c
join pg_namespace n on n.oid = c.relnamespace
where n.nspname = 'public'
and c.relkind = 'r'
order by c.relrowsecurity, c.relname;Cada linha com rls_enabled = false é uma tabela que a chave pública alcança. Tabelas criadas no Table Editor já vêm com RLS ligado; tabelas criadas por SQL, que é como a maioria das ferramentas de IA as cria, não.
O Security Advisor do painel aponta o mesmo problema como RLS Disabled in Public. Se ele mostrar algum erro, comece por ali.
Passo 2: procure regras que liberam tudo
RLS ligado, mas generoso demais, deixa tudo tão aberto quanto RLS desligado. Liste suas regras:
select tablename, policyname, cmd, roles, qual, with_check
from pg_policies
where schemaname = 'public'
order by tablename, cmd;Olhe com atenção as regras em que qual ou with_check é simplesmente true, principalmente para os papéis anon ou public. Uma regra assim numa tabela profiles ou orders significa que qualquer pessoa lê todos os perfis ou todos os pedidos.
Passo 3: confirme por fora
Agora teste como um atacante faria: só com a chave pública. Encontre a URL do projeto e a chave em Project Settings → API e execute:
curl "https://SEU-PROJETO.supabase.co/rest/v1/profiles?select=*&limit=5" \
-H "apikey: SUA_CHAVE_PUBLICA"Como ler a resposta:
- Linhas que não são suas: a tabela está exposta. Corrija hoje.
- Uma lista vazia
[]: ou a tabela está vazia, ou o RLS está filtrando tudo, que é o que você quer. - Um erro de permissão: a tabela não pode ser acessada pela API. Também está bom.
Repita para cada tabela com dados pessoais, pagamentos ou qualquer coisa privada.
Passo 4: garanta que a chave secreta não está no app
O Supabase também fornece uma service role key (ou secret key, que começa com sb_secret_). Ela ignora o RLS por completo e só pode existir num servidor. Abra seu app publicado, aperte F12, vá em Sources e procure no JavaScript por service_role e sb_secret_. Se aparecer qualquer um dos dois, troque a chave no painel imediatamente e leve o código que precisava dela para uma função no servidor.
O que corrigir primeiro
- Troque qualquer chave secreta que tenha chegado ao navegador.
- Ligue o RLS em todas as tabelas do schema public:
alter table public.profiles enable row level security; - Substitua as regras
using (true)das tabelas privadas por regras ligadas ao usuário logado. - Rode o Passo 3 de novo e confirme que um estranho não recebe nada.
Ligar o RLS vai quebrar qualquer tela que dependia da tabela aberta. Isso é esperado: cada tela passa a precisar de uma regra que libere exatamente o que deve. Se o seu app foi gerado por IA e você não tem certeza de quais regras ele precisa, é exatamente por esse trabalho que o nosso Security Check começa.
SupabaseLovableRow Level SecurityApps feitos com IA
Continue lendo
Todos os artigos
Segurança de apps
Achou a chave secreta do Supabase no navegador? O que fazer na primeira hora
Uma chave service role ou secreta no frontend dá a qualquer pessoa acesso total ao banco. A ordem certa: revogar, substituir, olhar os logs e corrigir a causa.
5 min de leitura

Sites
Por que os e-mails do formulário do seu site caem no spam (e como SPF, DKIM e DMARC resolvem)
Mensagens do formulário do site vão para o spam ou nem chegam? Quase sempre o problema é o envio. O que verificar e os três registros de DNS que corrigem.
4 min de leitura