A ronda flagra. Sua Missão, o plano de conserto desta ronda, mostra o que fechar primeiro.
Resolva 2 itens críticos e a exposição cai para ~20 (Baixo).
Revisamos seu app inteirinho e a notícia é boa: dá pra ficar tranquilo rápido. Você já acertou em várias coisas — HTTPS, certificado e e-mail estão certos.
O que precisa de atenção agora são 2 brechas críticas: uma chave de administrador exposta e a proteção dos dados desligada. Juntas, elas deixam qualquer visitante ler e mudar os dados dos seus usuários. Parece assustador, mas o conserto é simples e está tudo explicado abaixo, com um prompt pronto pra colar na sua IA.
Quando os 2 itens críticos estiverem resolvidos, seu nível de exposição cai de Alto para Baixo.
Conclua os Objetivos da Missão abaixo pra ver sua exposição estimada cair em tempo real.
Sem jargão. Cada achado explica o que é, por que importa e traz o conserto pronto pra colar na sua IA.
A service_role é a chave de administrador do seu Supabase. Ela está escrita no JavaScript que qualquer visitante baixa só de abrir seu site.
o começo da chave que encontramos no seu código, encurtado por segurança “…” = trecho encurtado de propósito — a ronda não guarda o valor inteiro.
eyJhbGciOiJIUzI1Ni… · role: "service_role" · exp: 2077428374 · fonte: app.exemplo.com.br/assets/index-CBWCsxTw.js
Com ela, qualquer pessoa pode ler, alterar ou apagar todos os dados do seu app — usuários, pedidos, tudo. É o acesso mais perigoso que existe. Costuma acontecer quando a chave de servidor é usada no código do front por engano — ferramentas de IA fazem isso sem avisar.
Cole no chat da ferramenta que você já usa (Claude Code, Cursor, Lovable…).
eyJhbGciOiJIUzI1Ni… · role: "service_role" · exp: 2077428374 · fonte: app.exemplo.com.br/assets/index-CBWCsxTw.js
A “proteção por linha” (RLS) da sua tabela users está desligada. Sem ela, a regra vale pra todo mundo: qualquer um vê tudo.
a resposta que o seu banco devolveu ao nosso teste sem login
GET /rest/v1/users?select=* → 200 OK · 1.482 linhas retornadas
Hoje alguém consegue baixar a lista inteira de e-mails e dados dos seus 1.482 usuários sem nem fazer login. As ferramentas criam as tabelas, mas ligar o RLS fica por sua conta — e esse passo passa batido com frequência.
GET /rest/v1/users?select=* → 200 OK · 1.482 linhas retornadas
Sua API aceita pedidos de qualquer site (o “CORS” está liberado pra todos com *).
as permissões de origem que a sua API devolveu ao nosso teste
https://app.exemplo.com.br/rest/v1/ · Origin: https://evil.test → Access-Control-Allow-Origin: https://evil.test
Um site malicioso pode usar a sessão de quem está logado no seu app pra fazer ações em nome da pessoa (roubo de sessão).
https://app.exemplo.com.br/rest/v1/ · Origin: https://evil.test → Access-Control-Allow-Origin: https://evil.test
Seu site não tem uma Content-Security-Policy — uma regra que bloqueia scripts não autorizados de rodarem na página.
o que a resposta do seu site mostrou (ou deixou de mostrar) nesse cabeçalho
GET https://app.exemplo.com.br/ → resposta sem o header Content-Security-Policy
O cookie de sessão não tem as marcas Secure e SameSite, que o protegem em trânsito.
o cookie como o navegador o recebe — dá pra ver as marcações que faltam “…” = trecho encurtado de propósito — a ronda não guarda o valor inteiro.
Set-Cookie em https://app.exemplo.com.br/ → session=…; HttpOnly (sem Secure, sem SameSite)
Bom trabalho, comandante. Mantenha assim. 🛡️
A ronda básica é grátis e ilimitada. Em segundos você vê o que está exposto.
Rodar no meu app