1. API keys embutidas no JavaScript do seu frontend
Esse é o erro mais prejudicial e o mais fácil de cometer. Você pede para a sua ferramenta de IA "adicionar pagamentos com Stripe" ou "conectar com a OpenAI", e ela liga a chave secreta direto em um componente de cliente. O app funciona — e a sua chave secreta agora vai para o navegador de cada visitante, legível para qualquer um que abra o DevTools ou faça um grep no seu bundle JS.
Tudo que tem o prefixo NEXT_PUBLIC_ (ou VITE_, ou REACT_APP_) é embutido no bundle do cliente em tempo de build. Chaves secretas — sk_live_ da Stripe, sk- da OpenAI, URLs de banco de dados, chaves service-role — só devem ser lidas em código do lado do servidor: API routes, componentes de servidor ou edge functions.
A verificação rápida: abra o seu site publicado, veja o código-fonte da página e o JS empacotado, e procure por sk_live, sk- e os primeiros caracteres das chaves do seu .env. Se algum aparecer, primeiro rotacione a chave e depois mova a chamada para o servidor.
2. .env ou .git servidos direto da raiz do seu site
Um número surpreendente de apps publicados devolve tranquilamente o arquivo .env — ou o diretório .git inteiro — se você simplesmente pedir. Basta um servidor de arquivos estáticos mal configurado ou um template de framework que copia tudo para a pasta pública.
O impacto é total: credenciais de banco de dados, secrets de autenticação, API keys, tudo em um arquivo. Um diretório .git exposto é quase tão grave, porque um atacante consegue reconstruir todo o histórico do seu código, incluindo secrets que foram commitados e depois "removidos".
A verificação rápida leva dez segundos:
curl -i https://yourapp.com/.env
curl -i https://yourapp.com/.git/config
# Both should return 404 (or 403) — never 200.Arquivos .env expostos: o guia completo3. Sem Content-Security-Policy
As ferramentas de IA quase nunca adicionam cabeçalhos de segurança, e a CSP é a que mais importa. Sem ela, um único bug de injeção de HTML ou XSS em qualquer parte do seu app permite que um atacante execute JavaScript arbitrário nos navegadores dos seus usuários — roubando sessões e exfiltrando dados.
Uma boa política inicial para a maioria dos apps: default-src 'self', bloquear objetos e enquadramento, e permitir apenas as origens de scripts de terceiros que você realmente usa. Comece restrito e afrouxe com intenção — nunca o contrário.
// next.config.js
const csp = [
"default-src 'self'",
"script-src 'self'",
"style-src 'self' 'unsafe-inline'",
"img-src 'self' data:",
"base-uri 'none'",
"frame-ancestors 'none'",
"object-src 'none'",
].join("; ");
module.exports = {
async headers() {
return [{ source: "/:path*", headers: [{ key: "Content-Security-Policy", value: csp }] }];
},
};CSP explicada: diretivas, nonces e erros comuns4. Cookies de sessão sem Secure, HttpOnly e SameSite
Se a sua biblioteca de autenticação foi configurada por uma ferramenta de IA com as opções padrão, vale a pena verificar as flags do cookie de sessão. Um cookie sem HttpOnly pode ser lido por qualquer script injetado (transformando um pequeno XSS em uma tomada total da conta), um sem Secure pode vazar por HTTP puro, e um sem SameSite torna a falsificação de requisições entre sites (CSRF) muito mais fácil.
Abra o DevTools → Application → Cookies no seu app publicado. Todo cookie de sessão ou de autenticação deve mostrar os três: Secure, HttpOnly e SameSite=Lax (ou Strict).
5. HTTP que nunca vira HTTPS (e sem HSTS)
A maioria das plataformas de hospedagem te dá HTTPS automaticamente — mas muitos apps ainda respondem numa boa por HTTP puro sem redirecionar, ou redirecionam mas nunca enviam um cabeçalho Strict-Transport-Security. De qualquer forma, um usuário que digita o seu domínio na barra de endereços faz a primeira requisição sem criptografia, e essa requisição pode ser interceptada ou rebaixada antes do seu redirecionamento acontecer.
A correção são duas linhas de configuração: um redirecionamento permanente 301 de HTTP para HTTPS, mais um cabeçalho HSTS (max-age=31536000; includeSubDomains) para que os navegadores se recusem a rebaixar a conexão de novo.
6. CORS configurado para permitir tudo
Quando um frontend gerado com IA não consegue alcançar a própria API durante o desenvolvimento, a "correção" gerada é quase sempre Access-Control-Allow-Origin: * — às vezes com credenciais permitidas também. Isso diz a todos os sites da internet que eles podem chamar a sua API a partir do navegador dos visitantes deles.
Para uma API que serve o seu próprio frontend, a origem permitida deve ser exatamente o seu próprio domínio, e nada mais. CORS com curinga só é aceitável para APIs genuinamente públicas, sem autenticação e somente leitura.
7. Sem SPF ou DMARC no seu domínio
Este aqui não tem nada a ver com o código do seu app — tem a ver com o seu domínio. Sem os registros DNS SPF e DMARC, qualquer um pode enviar e-mail que diz ser de [email protected], e os servidores de e-mail que recebem não têm como saber que é falso. Isso é phishing contra os seus próprios usuários, usando a sua marca.
Dois registros DNS TXT resolvem isso. Se você envia e-mail por um provedor como Resend, Postmark ou SES, a documentação deles te dá o valor SPF exato; adicione uma política DMARC junto e endureça de p=none para p=quarantine assim que confirmar que o e-mail legítimo passa.
Verifique os sete de uma só vez
Todo item desta lista é detectável de fora, o que significa que você não precisa passar por ele na mão. O AppSafe roda todas essas verificações — além de SSL/TLS, subdomain takeover, source maps e mais — em um único escaneamento, dá uma nota de A a F ao resultado e te entrega um prompt de correção com IA para cada achado, que você pode colar direto no Cursor ou no Claude Code.
O escaneamento rápido na página inicial não exige cadastro. O escaneamento completo (incluindo as verificações de secrets expostos) só roda em domínios cuja propriedade você comprovou — de propósito, já que não vamos fazer grep nos bundles JS de outra pessoa em busca de chaves.