Pular para o conteúdo

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:

Tabelas do schema public e o status do RLS
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:

Todas as políticas de RLS do schema public
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:

Ler uma tabela com a chave pública
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

  1. Troque qualquer chave secreta que tenha chegado ao navegador.
  2. Ligue o RLS em todas as tabelas do schema public: alter table public.profiles enable row level security;
  3. Substitua as regras using (true) das tabelas privadas por regras ligadas ao usuário logado.
  4. 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

Este artigo também está disponível em: EnglishEspañol日本語中文

Todos os artigos