Lovable + Supabase: o checklist de segurança antes de colocar seu app no ar
Descubra se o Supabase do seu app Lovable está exposto. Checklist completo de RLS, chaves e permissões pra rodar antes de lançar em produção.
Sumário do artigo

Se você construiu seu app com Lovable e conectou o Supabase nos primeiros cliques, existe uma chance real de que qualquer pessoa com a chave pública do seu projeto consiga ler, ou até apagar, os dados dos seus usuários agora mesmo. Não é um cenário hipotético: uma pesquisa de segurança publicada em maio de 2025 encontrou 170 projetos Lovable, de uma amostra de 1.645, com tabelas do Supabase completamente abertas via chave anônima. Pouco mais de 10% dos apps analisados vazando dados por um único motivo: Row Level Security (RLS) desligada ou mal configurada.
Este post é o checklist que uso antes de considerar qualquer projeto pronto pra receber usuário de verdade. Você não precisa ser desenvolvedor pra seguir ele, mas precisa rodar cada passo, porque o Lovable não avisa quando gera uma tabela insegura.
O que é RLS e por que o Supabase depende inteiramente dela
Row Level Security é uma camada de segurança que vive dentro do PostgreSQL, o banco por trás do Supabase. Em vez de proteger os dados no backend (como você faria numa API tradicional em Node ou Laravel), o Supabase inverte a lógica: o controle de acesso mora no próprio banco, avaliado linha por linha a cada consulta.
O problema é o padrão de fábrica. Toda tabela nova criada por SQL, migration, ou por uma ferramenta de IA como o Lovable, nasce com RLS desligada. Isso significa que a tabela fica 100% pública pra qualquer requisição que use a chave anon, a chave pública que fica exposta no seu frontend (isso é esperado e normal). Sem uma política de RLS, essa chave não é uma porta trancada. É uma porta aberta.
Como saber se seu Supabase já está exposto agora
No painel do Supabase, vá em Table Editor e olhe cada tabela. Se ela não tiver o selo "RLS enabled" visível, ela está aberta. O próprio Supabase mostra um aviso amarelo nesse caso, dizendo que a tabela é legível e gravável por qualquer pessoa com a chave anon.
Pra confirmar na prática, pegue a URL do seu projeto e a chave anon (ambas públicas, tudo bem) e rode isso num terminal:
bash
curl 'https://SEU-PROJETO.supabase.co/rest/v1/NOME_DA_TABELA?select=*' \
-H "apikey: SUA_CHAVE_ANON" \
-H "Authorization: Bearer SUA_CHAVE_ANON"
Se a resposta trouxer linhas de dados que não deveriam ser públicas, a tabela está exposta. Se vier um array vazio ou erro de permissão, a política está funcionando.
Os 4 erros que o Lovable mais comete no Supabase
Erro | Por que acontece | Como corrigir |
|---|---|---|
Tabela sem RLS habilitada | É o padrão do Postgres pra tabelas novas, e o Lovable não liga sozinho |
|
Política liberal demais ( | A IA cria uma policy só pra "fazer funcionar" no teste, sem pensar em quem deveria ver o quê | Reescrever a policy comparando com o dono da linha |
Chave | O Lovable às vezes usa a chave que ignora RLS pra resolver um bug rápido, e ela vaza pro bundle JS | Buscar |
Sem verificação de e-mail ou limite de tentativas no login | O fluxo de autenticação padrão prioriza velocidade, não segurança | Ativar confirmação de e-mail e rate limiting no painel de Authentication |
Um exemplo de política correta, comparando com o dono da linha:
sql
ALTER TABLE pedidos ENABLE ROW LEVEL SECURITY;
CREATE POLICY "usuario_ve_proprios_pedidos"
ON pedidos
FOR SELECT
USING (auth.uid() = user_id);
CREATE POLICY "usuario_atualiza_proprios_pedidos"
ON pedidos
FOR UPDATE
USING (auth.uid() = user_id);
Se sua tabela for grande (dezenas de milhares de linhas ou mais), troque auth.uid() por (select auth.uid()) dentro da policy. Essa mudança deixa o Postgres cachear o resultado por consulta em vez de recalcular linha por linha, evitando que a policy vire gargalo de performance.
O checklist antes de lançar
Abra Table Editor e confirme o selo "RLS enabled" em toda tabela que o navegador consegue acessar.
Em Authentication → Policies, ative "Enable RLS on new tables" pra que tabelas futuras não nasçam abertas.
Busque
service_roleem todo o repositório. Se aparecer fora de uma Edge Function, mova.Abra seu arquivo de variáveis de ambiente. Toda variável que começa com
VITE_vai parar no navegador do usuário, então nenhuma delas pode ser um segredo.Ative confirmação de e-mail e senha forte em Authentication → Settings.
Adicione validação (Zod ou similar) em todo formulário que grava direto no banco, começando pelos mais sensíveis: cadastro, pagamento, configurações de conta.
Perguntas frequentes
O Lovable corrige isso sozinho?
Não. O Lovable prioriza gerar uma tela funcional rápido, e a responsabilidade de proteger os dados fica com quem publica o app.
Preciso saber SQL pra aplicar esse checklist?
O mínimo. Os comandos deste post são pra copiar e colar, ajustando só o nome da tabela e da coluna de dono.
RLS deixa meu app mais lento?
Só se a policy for escrita sem cuidado. Envolver auth.uid() num select resolve o caso mais comum de lentidão em tabelas grandes.
Como sei se já vazei dados antes de corrigir?
O teste com curl da seção anterior mostra na hora se uma tabela específica responde sem autenticação de verdade. Rode em todas antes de comemorar a correção.
Se você ainda está prototipando e vai usar o Lovable pra tirar a ideia do papel, isso não muda a velocidade da ferramenta. Só significa que, antes de mandar o link pro primeiro usuário real, esse checklist precisa estar 100% marcado.