Pular para o conteúdo

Noções de segurança

Cabeçalhos de segurança faltando: quando isso importa

Cabeçalhos de segurança faltando é o achado que nosso scanner mais imprime. Contra o que eles protegem e quando são a linha menos urgente do relatório.

Vlad Tkachenko8 min de leitura
A lista de cabeçalhos que um site devolve com cada página, com quatro de suas linhas apenas riscadas e vazias onde entraria um valor.

Em resumo

  • Cabeçalhos de segurança faltando é o achado mais comum que existe e, sozinho, ele quase não diz nada sobre alguém conseguir chegar aos seus dados.
  • Escaneamos 30.998 apps no ar. Dois em cada três dos que estavam sem cabeçalhos não tinham mais nada de errado.
  • Ainda assim vale corrigir, e isso vem depois das coisas que decidem quem pode ler o seu banco de dados.
  • Em alguns domínios de builders você não consegue defini-los, e deixar como está é uma resposta razoável.

Seu scan volta e quase todas as linhas estão verdes. Uma está âmbar: alguns cabeçalhos de segurança do navegador estão faltando. É a única coisa colorida da página, então parece a primeira de que cuidar.

Aqui está a parte que a maioria dos conselhos sobre isso erra. Cabeçalhos de segurança faltando é o achado que mais imprimimos e, sozinho, ele quase não diz nada sobre alguém conseguir chegar aos seus dados. Tratar isso como uma invasão significa ou corrigir no susto, na frente das coisas que de fato decidem quem lê o seu banco de dados, ou aprender que linhas âmbar são ruído, o que é pior.

Entre 12 e 14 de agosto de 2026 rodamos as mesmas nove verificações externas em 30.998 apps no ar feitos com Lovable, Bolt, v0, Replit e Base44. Dos apps em que essa verificação obteve resposta, 30.756 de 30.981 estavam sem pelo menos um cabeçalho. Os números completos estão no nosso relatório de varredura.

Cabeçalhos de segurança faltando são um problema?

É uma lacuna real e quase sempre a linha menos urgente do seu relatório.

Um cabeçalho de segurança é uma instrução curta que o seu servidor anexa a cada página que envia, endereçada ao navegador de quem visita e não à pessoa. Não deixe outro site colocar esta página dentro de um quadro. Não adivinhe que tipo de arquivo é este. Não passe o meu endereço completo quando alguém clicar para fora. São bilhetes para um ajudante que faz o que qualquer site mandar.

O resto do seu relatório é sobre fechaduras. Se o Row Level Security está ligado, se tem uma chave secreta no seu código, se um bucket de armazenamento lista o conteúdo: é isso que decide quem consegue chegar aos seus dados. Bilhete e fechadura a gente quer os dois, e o bilhete que você nunca escreveu não é o motivo pelo qual se perde um banco de dados.

Nossa nota trata assim. Um cabeçalho faltando tira cinco pontos de cem e não limita o teto, então um app cujo único achado é esse sai com 95 e nota A.

O que encontramos em 30.998 apps

Cabeçalhos faltando apareceram em quase tudo, e mal se mexeram junto com o resto do relatório.

25.821 desses apps obtiveram resposta das nove verificações, e é esse o grupo em que "não tinha mais nada" significa alguma coisa. Entre eles, 25.606 estavam sem pelo menos um cabeçalho e 215 tinham os cinco.

Apps sem cabeçalhos não tinham mais chance de ter outra coisa errada do que apps que tinham os cinco.

Dos 25.606 apps sem pelo menos um cabeçalho, 17.043 não tinham mais nada de errado. Dois em cada três. Era o único problema do relatório deles.

Agora leia a outra linha, que é a parte que nos surpreendeu. Dos 215 apps que tinham os cinco cabeçalhos definidos, 145 tinham outra coisa errada. Essa é uma taxa de problemas reais mais alta do que entre os apps sem cabeçalhos, e não mais baixa.

Não medimos o porquê, e a leitura honesta é estreita: seja lá o que essas varreduras encontraram, o achado sobre cabeçalhos não previu isso. Um app com um conjunto perfeito de cabeçalhos não era um app mais seguro nos nossos dados. A explicação mais provável é que definir cabeçalhos já significa que alguém configurou uma hospedagem de verdade, o que costuma significar um app maior com mais coisa para dar errado, mas isso é um palpite e não testamos.

Se você quiser ver quais dessas linhas o seu próprio app produz, o scan é gratuito, leva uns 20 segundos e não precisa de conta: escaneie seu app.

O que cada cabeçalho realmente faz

Cada um desliga um comportamento do navegador que vem ligado de fábrica.

CabeçalhoO que ele diz ao navegadorO que a ausência dele permite
Content-Security-PolicyDe quais lugares esta página pode carregar código e estilosUm script injetado consegue mandar dados para onde quiser
Strict-Transport-SecurityVolte sempre por HTTPS, nunca por HTTP puroUma visita numa rede não confiável pode ser empurrada para HTTP puro
X-Frame-OptionsNão deixe outro site exibir esta página dentro de um quadroSua página pode ser carregada invisível dentro da de outra pessoa
X-Content-Type-OptionsConfie no tipo de arquivo que eu passei e não adivinhe pelo conteúdoUm arquivo que alguém subiu pode ser servido como um tipo de arquivo diferente
Referrer-PolicyQuanto deste endereço repassar quando alguém clicar para foraURLs completas, com tudo que houver nelas, chegam a servidores de terceiros

Dois deles se sobrepõem, e o scanner leva isso em conta. Uma Content-Security-Policy que contenha frame-ancestors faz o mesmo trabalho de X-Frame-Options, então a nossa verificação conta qualquer um dos dois e não exige os dois.

Quando um cabeçalho faltando é o problema inteiro

Quando o seu app tem algo que vale a pena clicar enquanto a pessoa está logada.

Esse é o caso do clickjacking, e é o único que funciona sem nenhum outro erro. Alguém carrega o seu app num quadro invisível dentro de uma página que controla e põe os botões dele por cima dos seus, de modo que quem já está logado clica no que parece a página dele e acerta um controle seu: o botão que apaga uma conta, aprova uma transferência ou troca um endereço de e-mail.

Com o cabeçalho, o navegador se recusa a desenhar a sua página dentro de outro site. Sem ele, isso é uma coisa perfeitamente prevista.

Quem visita está logado, então a ação carrega a sessão dessa pessoa. Nada no seu banco de dados precisa estar mal configurado. O que faz isso funcionar é que nunca disseram ao navegador para recusar.

Referrer-Policy tem uma versão menor do mesmo formato. Se uma página sua com sessão aberta carrega algo identificável na URL e aponta para um servidor de imagens ou um script de analytics, o endereço inteiro viaja junto com o clique. Quem opera aquele outro servidor vê onde o seu usuário estava.

Os outros três são condicionais. Eles importam quando outra coisa já deu errado, e o trabalho deles é manter isso pequeno. Uma Content-Security-Policy limita o que um script injetado consegue fazer com o acesso que tem. X-Content-Type-Options importa se estranhos podem subir arquivos para você. Strict-Transport-Security cobre quem usa o seu app numa rede que não controla.

Eu preciso de cabeçalhos de segurança?

Precisa. Eles são baratos, e vêm depois dos achados que decidem quem pode ler o seu banco de dados.

A ordem que sai da medição acima: primeiro tudo que estiver como crítico ou alto no seu relatório, cabeçalhos depois. Se o seu relatório tem só essa linha, como foi o caso de 17.043 dos apps que escaneamos, então os cabeçalhos ficam no topo da sua lista por eliminação.

Dois dos cinco não custam nada para acertar. X-Content-Type-Options: nosniff e Referrer-Policy: strict-origin-when-cross-origin são uma linha cada, não têm valor errado a escolher e não conseguem quebrar um app que funciona. X-Frame-Options: DENY também é uma linha, e vale olhar antes se você embute o seu próprio app em algum lugar de propósito.

Content-Security-Policy é o que dá trabalho de verdade. Uma primeira tentativa costuma bloquear algo de que a sua própria página precisava, e o sintoma é uma função que para de funcionar sem avisar. Suba como Content-Security-Policy-Report-Only, que conta o que teria bloqueado sem bloquear nada, e leia uma semana de relatórios antes de ligar.

Como adicioná-los

Naquilo que de fato serve o seu app para a internet, que muitas vezes não é o lugar onde você o constrói.

A maioria dos builders publica numa hospedagem que é dona da resposta, então a configuração mora lá. Na Vercel é headers dentro do vercel.json. No Netlify e no Cloudflare Pages é um arquivo _headers na raiz do que você publica. Atrás do proxy da Cloudflare é uma Transform Rule. Se você roda um servidor próprio, é a sua configuração de nginx ou Caddy.

O que dá para saber sobre cabeçalhos depois de defini-los é que eles saem sem ninguém encostar neles. Mudar para um domínio próprio, colocar um proxy na frente, trocar de hospedagem, mexer numa configuração de framework: os cabeçalhos que você adicionou moram em um desses lugares, e qualquer um desses passos pode deixá-los para trás. Nada te avisa. A página continua funcionando e a configuração sumiu.

É para esse tipo de coisa que existe o Reeve Monitor. Ele roda a verificação completa de novo a cada hora em até três apps, acompanha a disponibilidade a cada 60 segundos e te avisa quando um resultado muda, em vez de esperar você olhar. O Monitor só acompanha, então se você também quiser uma cópia do seu banco de dados em algum lugar que o seu builder não alcance, isso é o Care, e ele cobre o Supabase.

O que fazer agora

O que fazer

  • Leia primeiro o resto do relatório. Se tiver algo marcado como crítico ou alto, o trabalho é esse, e os cabeçalhos esperam.
  • Coloque hoje X-Content-Type-Options: nosniff e Referrer-Policy: strict-origin-when-cross-origin. Uma linha cada, nada a decidir, nada a quebrar.
  • Coloque X-Frame-Options: DENY se as pessoas fazem login no seu app e conseguem fazer algo pesado com um clique.
  • Deixe Content-Security-Policy por último e comece em modo report-only, para descobrir antes dos seus visitantes o que ele quebra.
  • Se você está num subdomínio de builder sem configuração de cabeçalhos, deixe o achado quieto. Ele ainda não é seu.
  • Confira de novo depois de mudar de domínio, adicionar um proxy ou trocar de hospedagem. É aí que eles somem.

Cabeçalhos valem uma tarde tranquila quando o resto do relatório estiver limpo. Se você prefere percorrer a lista inteira em ordem, a checklist de segurança de 10 minutos cobre o que desligar num app recém-lançado, e os achados que de fato decidem quem lê o seu banco de dados são os primeiros a tirar do caminho.

Perguntas frequentes

Meu scan diz que estão faltando cabeçalhos de segurança. Meu app foi hackeado?

Não. Um cabeçalho faltando é uma configuração que nunca foi ligada, e não é prova de que algo aconteceu. Nada no achado envolve alguém chegando aos seus dados ou à sua conta. Ele descreve uma instrução que o seu site poderia estar dando aos navegadores que o visitam e no momento não dá.

Qual cabeçalho de segurança eu devo colocar primeiro?

X-Content-Type-Options e Referrer-Policy, porque os dois são uma linha só, nenhum tem um valor errado a escolher e nenhum consegue quebrar um app que funciona. Depois X-Frame-Options, se as pessoas fazem login no seu app. Depois Strict-Transport-Security. Content-Security-Policy por último, porque é o único dos cinco que exige pensar de verdade e o único que pode impedir os seus próprios scripts de rodar.

Estou no domínio padrão do meu builder e não existe configuração de cabeçalhos. E agora?

Deixe como está. Quando o seu app é servido a partir de um subdomínio da plataforma, os cabeçalhos de resposta são escolha da plataforma e não sua, e não existe arquivo que você possa adicionar para mudá-los. Conecte um domínio próprio se quiser controle sobre isso, porque é o domínio que permite colocar uma hospedagem sua ou um proxy na frente do app. Até lá, gaste o esforço nos achados que cabe a você corrigir.

Uma Content-Security-Policy pode quebrar o meu app?

Pode, e esse é o resultado normal de uma primeira tentativa. Uma política que não permite scripts inline vai parar os scripts inline, inclusive os que o seu builder gerou, e a página fica em branco ou perde uma função, com um erro que só aparece no console do navegador. Comece com Content-Security-Policy-Report-Only, que relata o que teria bloqueado sem bloquear nada, e leia os relatórios por uma semana antes de ligar de verdade.

Cabeçalhos de segurança ajudam se o meu banco de dados pode ser lido por qualquer um?

Não. Cabeçalhos são instruções para os navegadores que visitam o seu site, e quem lê o seu banco de dados direto não está usando navegador nem visitando o seu site. Essa requisição vai direto para o seu provedor de banco de dados e nunca toca nas suas páginas, então nenhum cabeçalho colocado nelas se aplica a ela. Quem decide essa é o Row Level Security.

Escrito por

Vlad Tkachenko

Fundador da Reeve

Passo meus dias olhando apps criados com Lovable, Bolt, v0, Cursor e Replit, e a curta lista de erros que aparecem neles sem parar.

Mais sobre o autor

Leia depois

Todos os artigos

Não sabe como está o seu próprio app?

Faça um scan gratuito e receba uma nota clara de A a F em cerca de 20 segundos. Sem conta e sem cartão.

Verificar meu app grátis

Verificação externa automatizada, não uma auditoria completa. A ausência de achados não é garantia de segurança.