AWS HubAWS HubSão Paulo operando · 2 eventos no mundo

Pesquisa com 560 apps feitos por agentes de código expõe falhas em headers e chaves no browser

Levantamento do Sitecheckly analisou 474 aplicações listadas no Made with Lovable e encontrou lacunas recorrentes em CSP, proteção contra clickjacking e configuração de Supabase exposta no browser.

Por Caio Mendes7 min de leitura

Ilustração gerada por IA

Uma pesquisa publicada pelo Sitecheckly na DEV Community levantou dados concretos sobre um problema que todo mundo que usa agente de código já suspeitava: o app sobe rápido, mas a configuração de segurança fica para depois (quando fica). O fetch dos dados aconteceu em 8 de novembro de 2026, sobre 560 aplicações públicas listadas no Made with Lovable, a vitrine de projetos construídos com a Lovable. Das 560, 474 serviram uma página analisável; o restante não respondeu ou bloqueou a coleta.

A amostra tem viés: só entrou quem decidiu listar o projeto publicamente, o que tende a puxar para apps já lançados e apresentáveis. Não é uma amostra de todo app feito com IA nem de todo projeto Lovable. Mas é dado real, coletado com metodologia passiva e documentada, não achismo de post de LinkedIn.

O placar geral engana

A pontuação média de segurança dos apps analisados foi 76,3 de 100. O grupo de comparação, o Tranco top-sites (os sites mais acessados da web), ficou em 77,1. À primeira vista, parece empate. O problema é que essa média esconde diferenças grandes quando você olha item por item.

Checagem observávelApps feitos com IASites do topo (Tranco)
Sem Cross-Origin-Opener-Policy (COOP)98%95%
Sem Content-Security-Policy (CSP)92%66%
Sem proteção contra clickjacking89%43%
Sem registro DMARC72%24%
Sem registro SPF69%19%
Scripts de terceiros sem Subresource Integrity30%61%

Repare que a última linha inverte a lógica: os apps feitos com IA saem melhor que os sites do topo em Subresource Integrity (SRI). Isso não cancela o resto da tabela, só mostra que o problema não é "IA gera código ruim" de forma genérica. O gap concentra em headers de browser e registros de DNS que ninguém configurou, provavelmente porque o agente nunca foi instruído a fazer isso.

CSP, COOP e clickjacking: o que o agente não escreve sozinho

Content-Security-Policy ausente em 92% dos apps é o número que mais deveria incomodar quem usa Cursor, Claude Code ou Lovable para subir produto. CSP é o header que diz ao browser de onde ele pode carregar script, estilo, imagem e conexão; sem ele, um XSS que normalmente seria contido vira execução livre. A pesquisa recomenda configurar a política para os recursos reais do seu app, não copiar uma política de outro projeto: uma CSP genérica pode travar seu próprio fetch() para a API ou bloquear o CDN de fonte que você usa.

O mesmo vale para proteção contra clickjacking (via X-Frame-Options ou a diretiva frame-ancestors da própria CSP), ausente em 89% dos apps contra 43% dos sites do topo. E para COOP, que isola a janela do seu app de outras abas maliciosas: 98% dos apps de IA não têm, contra 95% dos sites do topo — aqui a diferença é pequena, e vale lembrar que ambos os grupos vão mal nesse item específico.

Nenhum desses headers o agente de código adiciona por padrão quando você pede "crie um app de X". Eles vivem na configuração de deploy (Vercel, Netlify, CloudFront) ou no middleware do framework, e normalmente só entram se alguém souber que precisa pedir.

DNS fica esquecido: CAA, SPF e DMARC

Além dos headers, a pesquisa checou registros DNS que não têm nada a ver com o código do app, mas protegem o domínio: CAA (restringe quem pode emitir certificado TLS para o domínio), SPF e DMARC (ambos de autenticação de e-mail, usados contra spoofing). 78% dos apps analisados não têm registro CAA, 72% não têm DMARC e 69% não têm SPF — contra 24% e 19% respectivamente nos sites do topo.

Esses três não aparecem em nenhum header HTTP nem em código: são configuração do provedor de DNS, geralmente de quem administra o domínio, não de quem escreve o front-end. Faz sentido que o agente de código nunca mexa nisso: ele nem tem acesso ao painel de DNS. Mas é um lembrete de que "meu app tá seguro" precisa incluir uma conversa com quem cuida do domínio, não só revisão de código.

Supabase no browser: a key pública não é o vazamento

Aqui está o ponto que mais gera pânico equivocado. 55% dos apps (262 de 474) carregam Supabase diretamente do browser, e 52% (247) têm uma chave anon ou publishable do Supabase visível no código da página. A pesquisa é explícita: isso não é, por si só, uma vulnerabilidade. Essas chaves são feitas para rodar no client.

O que realmente protege os dados é o Row Level Security (RLS) do Postgres por trás do Supabase. Se você gerou o schema com um agente e ele criou as tabelas sem política de RLS, qualquer usuário anônimo com a chave pública (que está, literalmente, no seu bundle.js) pode ler ou escrever o que quiser. A chave não vaza nada sozinha; a ausência de política é que vaza.

O checklist que a pesquisa sugere para quem mantém um projeto Supabase:

  • Confirme quais tabelas o client realmente precisa acessar.
  • Teste o que um visitante não autenticado consegue fazer.
  • Teste o que um usuário logado consegue ler e alterar.
  • Confirme que requisições fora dessas permissões são negadas.
  • Nunca deixe a service_role key fora do servidor; ela ignora RLS por completo.

Um scanner passivo de fora não enxerga sua política de RLS. Achar a chave anon no código não responde se o banco está exposto; só um teste manual, criando um usuário de teste e tentando ler o que ele não deveria, responde isso.

Firebase segue a mesma lógica

O SDK JavaScript do Firebase também é feito para rodar no browser, e a pesquisa não chegou a medir taxa de uso de Firebase entre os apps. O recado é o mesmo do Supabase: configuração de client não substitui regra de autorização. Quem usa Firebase precisa revisar as Firebase Security Rules e testar explicitamente o que cada tipo de usuário pode e não pode fazer, antes de assumir que está protegido.

As falhas raras, mas graves: chave secreta e chamada direta de API de IA

Aqui os números são pequenos em percentual, mas graves em natureza: 0,2% dos apps (1 de 474) tinha uma chave secreta exposta no próprio código da página. Separadamente, 1,7% (8 apps) chamavam uma API de provedor de IA diretamente do browser. A pesquisa avisa para não presumir que são os mesmos apps: são achados distintos.

Se uma chave secreta aparece em código shippado, o protocolo é claro e não aceita meio-termo:

  1. Remova a credencial do código-fonte e do build de produção.
  2. Revogue ou gire a chave no provedor; editar o código não invalida a chave antiga.
  3. Revise o histórico de uso da chave no painel do provedor, atrás de atividade que você não reconhece.
  4. Mova a chamada que precisa da credencial para um endpoint no servidor.
  5. Aplique autorização e limite de uso nesse endpoint; ele vira parte da sua borda de acesso, não só um esconderijo pra chave.

Esse é exatamente o tipo de erro que um agente comete quando você pede "integre com a API da OpenAI" sem especificar onde a chamada deve morar: ele resolve o problema mais curto (chamar direto do front) e deixa a credencial no .env que vira parte do bundle.

Prompt de sistema exposto: 1,5% dos apps

7 dos 474 apps (1,5%) expunham o system prompt da aplicação em JavaScript visível. A pesquisa, apoiada no OWASP LLM07 (System Prompt Leakage), é clara: um prompt não é secreto por natureza, mas vira problema quando contém credencial, instrução sensível ou regra de negócio que a aplicação trata como controle de acesso. Instruir o modelo a "não revelar X" nunca substitui aplicar essa regra no código do servidor.

O que o método não prova

A coleta foi inteiramente passiva: buscou a home page e até quatro arquivos de script próprios do app, sem login, sem chamada de API ou banco, respeitando robots.txt e sem executar JavaScript. Isso identifica configuração observável nos arquivos buscados; não prova que RLS está certo, não vê código fora do que foi buscado e não transforma ausência de achado em prova de ausência de falha.

Para quem constrói com agente de código, o recado prático é separar duas perguntas que a pesquisa trata como distintas o tempo todo: "o que está configurado publicamente?" (headers, DNS, chaves públicas) e "o que está autorizado de verdade?" (RLS, Security Rules, endpoints de servidor). O agente ajuda bastante na primeira pergunta quando você pede explicitamente; a segunda continua sendo trabalho de quem revisa antes de apertar deploy.

Fonte: DEV Community — #vibecoding

Serviços neste textoAgentes de código

Este artigo foi escrito por Caio Mendes. Conteúdo produzido pela redação de agentes de IA do AWS Hub, a partir de fontes oficiais citadas no texto. Saiba como produzimos no expediente.

Newsletter semanal

A semana da AWS, em português

Os lançamentos que importam, o que chegou à região São Paulo e o melhor tutorial da semana. Toda sexta, gratuita.