Cabeçalhos HTTP de segurança: CSP, HSTS e os outros

Quais cabeçalhos HTTP de segurança configurar, com valores de partida, o que cada um quebra se errar e como implantar a CSP sem derrubar o site.

Checar meu site grátisVer os planos
Nesta página 11 min de leitura
  1. Resumo: valores de partida e o que pode quebrar
  2. Strict-Transport-Security (HSTS)
  3. Content-Security-Policy (CSP)
  4. X-Content-Type-Options
  5. Referrer-Policy
  6. Permissions-Policy
  7. X-Frame-Options ou frame-ancestors
  8. Cross-Origin-Opener-Policy e Cross-Origin-Resource-Policy
  9. Cabeçalhos que não devem mais ser usados
  10. Um conjunto inicial completo
  11. Como verificar o seu site

Os cabeçalhos HTTP de segurança que valem para quase todo site são: Strict-Transport-Security (força HTTPS), Content-Security-Policy (limita scripts e quem pode exibir a página num iframe), X-Content-Type-Options: nosniff, Referrer-Policy e Permissions-Policy. X-Frame-Options ainda serve como reserva para navegadores antigos, e Cross-Origin-Opener-Policy e Cross-Origin-Resource-Policy isolam a página de outros sites. X-XSS-Protection, Expect-CT e Feature-Policy não devem mais ser usados. A CSP é o que dá mais trabalho e o que mais quebra; ela deve entrar primeiro em modo de relatório.

Este texto cobre o comportamento dos navegadores e as recomendações da MDN, da OWASP e do W3C em outubro de 2026. Ele faz parte do guia de segurança básica de um site, que trata de HTTPS, arquivos expostos, versões e cookies.

Resumo: valores de partida e o que pode quebrar

Os valores abaixo são um ponto de partida comum, baseado nas referências citadas em cada seção. Não são os únicos corretos: cada site precisa ajustar conforme o que usa.

CabeçalhoValor de partidaO que pode quebrar
Strict-Transport-Securitymax-age=63072000; includeSubDomainsSubdomínios que ainda não têm HTTPS ficam inacessíveis
Content-Security-PolicyPolítica com nonce, object-src 'none', base-uri 'none' e frame-ancestorsScripts inline, eventos onclick, eval(), widgets de terceiros
X-Content-Type-OptionsnosniffScripts e CSS servidos com Content-Type errado
Referrer-Policystrict-origin-when-cross-originFerramentas que dependem do caminho completo de origem em outro domínio
Permissions-Policycamera=(), microphone=(), geolocation=()Recursos que o site ou um iframe de parceiro usa de fato
X-Frame-OptionsDENY ou SAMEORIGINExibição legítima do site dentro de iframes
Cross-Origin-Opener-Policysame-origin, ou same-origin-allow-popups se houver login ou pagamento em pop-upPop-ups de OAuth e pagamento que conversam com a janela que os abriu
Cross-Origin-Resource-Policysame-siteArquivos do seu domínio usados por outros sites

Strict-Transport-Security (HSTS)

O HSTS diz ao navegador que aquele host só pode ser acessado em HTTPS durante max-age segundos. Depois de receber o cabeçalho, o navegador converte sozinho os pedidos http em https e não deixa o usuário ignorar erros de certificado (MDN: Strict-Transport-Security). Três detalhes importam:

  • O cabeçalho só vale se vier numa resposta HTTPS; enviado em http, é ignorado.

  • Ele só protege a partir da segunda visita, porque o navegador precisa ter recebido o cabeçalho uma vez. A lista de pré-carregamento dos navegadores (preload) fecha essa brecha.

  • includeSubDomains estende a regra a todos os subdomínios, presentes e futuros.

Strict-Transport-Security: max-age=63072000; includeSubDomains

A Mozilla recomenda no mínimo seis meses e sugere dois anos (63072000) (MDN: guia prático de TLS); o ASVS 5.0 pede no mínimo um ano e, a partir do nível 2, a inclusão dos subdomínios (ASVS 5.0, requisito 3.4.1). Recomendação de implantação: comece com um max-age curto, confira que tudo funciona e só então aumente, porque o navegador vai lembrar da regra pelo prazo inteiro. A OWASP alerta que um HSTS mal configurado ou um problema de certificado pode deixar usuários sem acesso durante todo o max-age (OWASP HTTP Headers Cheat Sheet).

Para entrar na lista de pré-carregamento, o site precisa de certificado válido, redirecionar http para https no mesmo host, ter HTTPS em todos os subdomínios e enviar max-age de pelo menos um ano com includeSubDomains e preload. A saída da lista é lenta (pode levar meses para chegar aos usuários) e outros navegadores não têm obrigação de acompanhar a remoção (hstspreload.org). Só faça o pedido se todos os subdomínios, inclusive os internos, vão ficar em HTTPS a longo prazo.

Content-Security-Policy (CSP)

A CSP é uma lista de regras que diz ao navegador de onde a página pode carregar scripts, estilos, imagens, iframes e para onde pode enviar dados. Seu uso principal é reduzir o efeito de XSS (cross-site scripting, a injeção de script na página): mesmo que um atacante consiga inserir um <script>, o navegador não o executa se ele não cumprir a política. Ela é uma camada a mais e não substitui a correção das falhas de XSS (web.dev: strict CSP).

Lista de domínios ou política estrita com nonce

Há dois jeitos de escrever a regra de scripts. O antigo é listar domínios permitidos (script-src 'self' https://cdn.exemplo.com). O recomendado pela MDN e pelo web.dev é a chamada CSP estrita, baseada em nonce ou hash (MDN: guia de CSP; web.dev: strict CSP). O ASVS 5.0 aceita as duas formas no nível 2, desde que a política tenha object-src 'none' e base-uri 'none', e exige nonce ou hash por resposta no nível 3 (ASVS 5.0, requisito 3.4.3).

Um nonce é um valor aleatório que o servidor gera a cada resposta, coloca no cabeçalho e repete no atributo nonce de cada <script> legítimo. O navegador só executa os scripts que trazem o valor certo. O nonce precisa ser imprevisível e diferente em cada resposta, e deve ser inserido pelo sistema de templates, nunca em todos os <script> da página de forma indiscriminada, para não carimbar também um script injetado (MDN: guia de CSP).

Content-Security-Policy:
  script-src 'nonce-R4nd0mPorResposta' 'strict-dynamic';
  object-src 'none';
  base-uri 'none';
  frame-ancestors 'self'

<script nonce="R4nd0mPorResposta" src="/js/app.js"></script>

'strict-dynamic' faz com que scripts criados por um script já confiável também rodem. Isso permite que bibliotecas e widgets de terceiros carreguem seus próprios arquivos sem que você liste cada domínio (web.dev: strict CSP). Para páginas estáticas ou servidas de cache, o web.dev recomenda hash no lugar de nonce: 'sha256-...' calculado sobre o conteúdo de cada script inline. Um nonce gravado numa página em cache se repete para todos os visitantes e perde o sentido.

frame-ancestors

A diretiva frame-ancestors define quais páginas podem exibir o site dentro de um <iframe>, o que protege contra clickjacking (quando outro site mostra o seu por baixo de botões falsos). A MDN recomenda 'none' para sites que não precisam ser incorporados (MDN: guia de CSP). Ela não herda o valor de default-src e não funciona em meta tag (MDN: frame-ancestors).

Content-Security-Policy: frame-ancestors 'none'
Content-Security-Policy: frame-ancestors 'self' https://parceiro.exemplo.com

Modo somente relatório

O cabeçalho Content-Security-Policy-Report-Only aplica a mesma sintaxe sem bloquear nada: o navegador só registra e envia as violações (MDN: Content-Security-Policy-Report-Only). Os dois cabeçalhos podem ser enviados juntos; nesse caso a política normal é aplicada e a de relatório só gera avisos, o que permite testar uma versão mais rígida sem mexer na que está valendo (MDN: guia de CSP).

Os relatórios vão para o endereço definido no cabeçalho Reporting-Endpoints e referenciado pela diretiva report-to. A diretiva antiga report-uri está obsoleta, mas a MDN recomenda declarar as duas enquanto report-to não funcionar em todos os navegadores (MDN: guia de CSP; W3C: CSP Level 3).

Reporting-Endpoints: csp="https://exemplo.com.br/csp-relatorios"
Content-Security-Policy-Report-Only:
  script-src 'nonce-R4nd0mPorResposta' 'strict-dynamic';
  object-src 'none';
  base-uri 'none';
  report-uri https://exemplo.com.br/csp-relatorios;
  report-to csp

Como implantar a CSP sem derrubar o site

  1. Liste os scripts e recursos de cada tipo de página (home, produto, checkout, área logada) pela aba Network do DevTools.

  2. Escolha nonce, se as páginas são geradas no servidor a cada requisição, ou hash, se são estáticas ou ficam em cache (web.dev).

  3. Ajuste o código que a política vai bloquear: troque eventos inline como onclick por addEventListener, troque links javascript: por eventos e substitua eval() (por exemplo, por JSON.parse()) (web.dev).

  4. Publique a política em Content-Security-Policy-Report-Only com um endpoint de relatórios.

  5. Acompanhe os relatórios por tempo suficiente para cobrir todos os tipos de página e fluxos, incluindo checkout e campanhas sazonais, e corrija ou libere cada origem legítima.

  6. Troque para Content-Security-Policy e mantenha o envio de relatórios.

  7. Revise a política no CSP Evaluator ou no Lighthouse antes e depois da troca, como sugere o web.dev.

O que costuma quebrar

  • Scripts inline sem nonce ou hash, inclusive os que plugins e temas imprimem na página.

  • Atributos de evento (onclick, onload) e links javascript:, que a CSP estrita bloqueia.

  • Bibliotecas que usam eval() ou new Function(). Liberar com 'unsafe-eval' enfraquece a política (web.dev).

  • Nonce em página guardada em cache, que repete o valor e faz scripts falharem ou deixa a proteção sem efeito.

  • Com política de lista de domínios: qualquer origem nova (um pixel, um chat, uma fonte) fica bloqueada até alguém atualizar a lista.

X-Content-Type-Options

Com nosniff, o navegador para de adivinhar o tipo do arquivo pelo conteúdo e usa o Content-Type declarado. Requisições de script são bloqueadas se o tipo não for de JavaScript, e de folha de estilo se não for text/css. Isso evita, por exemplo, que um arquivo enviado por usuário como texto seja executado como HTML ou script (MDN: X-Content-Type-Options). O ASVS pede o cabeçalho em todas as respostas (requisito 3.4.4).

X-Content-Type-Options: nosniff

O que quebra: arquivos servidos com tipo errado, como um .js entregue como text/plain. Antes de ativar, confira o Content-Type dos seus scripts e CSS, principalmente os gerados dinamicamente.

Referrer-Policy

O cabeçalho Referer conta ao site de destino de onde o visitante veio. Se o endereço tiver dados no caminho ou na query string (um token, um e-mail, um número de pedido), eles vazam para terceiros. A Referrer-Policy controla quanto desse endereço é enviado. Quando o site não define nada, o padrão dos navegadores hoje é strict-origin-when-cross-origin: o endereço completo para o próprio site, só a origem para outros sites em HTTPS e nada quando a conexão cai para HTTP (MDN: Referrer-Policy).

Referrer-Policy: strict-origin-when-cross-origin

A OWASP recomenda declarar o cabeçalho em vez de depender do padrão do navegador e usa esse valor como exemplo (OWASP HTTP Headers Cheat Sheet); a lista de valores do OWASP Secure Headers Project vai além e sugere no-referrer (headers_add.json). no-referrer é mais restritivo, mas pode atrapalhar ferramentas de análise que dependem da origem do tráfego. Evite unsafe-url, que envia o endereço completo até para destinos em HTTP.

Permissions-Policy

A Permissions-Policy liga ou desliga recursos do navegador, como câmera, microfone, geolocalização e pagamento, para a página e para os iframes dentro dela. () desliga o recurso em todo lugar; self libera só para a mesma origem; uma origem entre aspas libera para aquele domínio (MDN: Permissions-Policy).

Permissions-Policy: camera=(), microphone=(), geolocation=()
Permissions-Policy: geolocation=(self "https://mapas.exemplo.com"), microphone=()

A recomendação da OWASP é desligar tudo o que o site não usa (OWASP HTTP Headers Cheat Sheet). A MDN marca o cabeçalho como experimental e diz que ele não funciona em alguns navegadores muito usados, então trate-o como proteção adicional, não como a única barreira. O que quebra: um iframe de parceiro (mapa, vídeo, pagamento) que precisa de um recurso desligado. No iframe, o atributo allow concede o recurso dentro do limite que o cabeçalho permite.

X-Frame-Options ou frame-ancestors

X-Frame-Options foi o primeiro cabeçalho contra clickjacking. Aceita DENY (ninguém exibe a página em iframe) e SAMEORIGIN (só páginas da mesma origem). O valor ALLOW-FROM é obsoleto e faz navegadores modernos ignorarem o cabeçalho inteiro, e o cabeçalho não tem efeito em meta tag (MDN: X-Frame-Options).

A diretiva frame-ancestors da CSP faz o mesmo com mais opções, como liberar domínios específicos. A especificação da CSP define que, quando há uma política com frame-ancestors sendo aplicada, o navegador ignora o X-Frame-Options (W3C: CSP Level 3, seção 6.4.2.2). O ASVS 5.0 trata o X-Frame-Options como obsoleto e pede frame-ancestors (requisito 3.4.6). Recomendação: use frame-ancestors como regra principal e mantenha um X-Frame-Options coerente para navegadores antigos. Ele não atrapalha os novos, que já o ignoram nesse caso.

Cross-Origin-Opener-Policy e Cross-Origin-Resource-Policy

O Cross-Origin-Opener-Policy (COOP) decide se a sua página compartilha o contexto de navegação com janelas de outros sites que ela abriu ou que a abriram. Com same-origin, uma janela de outro domínio fica isolada e perde a referência window.opener. Isso quebra fluxos de login (OAuth) e de pagamento em pop-up que devolvem o resultado para a janela original; para esses casos existe same-origin-allow-popups (MDN: Cross-Origin-Opener-Policy). O ASVS pede um dos dois valores nas respostas que abrem documentos (requisito 3.4.8).

Cross-Origin-Opener-Policy: same-origin-allow-popups

O Cross-Origin-Resource-Policy (CORP) vai no recurso, não na página. Ele diz quais origens podem carregar aquele arquivo em requisições sem CORS, como <img> e <script>: same-origin, same-site ou cross-origin (MDN: Cross-Origin-Resource-Policy). A Mozilla lista o CORP entre as proteções contra ataques de canal lateral especulativo (MDN: guias práticos), e a OWASP sugere same-site. O que quebra: imagens, fontes ou scripts do seu domínio usados por outros sites, como um widget que você distribui. Esses arquivos precisam de cross-origin.

O par Cross-Origin-Embedder-Policy: require-corp com COOP same-origin ativa o isolamento entre origens, necessário para recursos como SharedArrayBuffer (MDN). O COEP bloqueia recursos de outras origens que não autorizem o uso por CORP ou CORS (OWASP). Opinião: num site institucional ou loja que não precisa desse isolamento, o COEP costuma custar mais (anúncios, vídeos e widgets bloqueados) do que entrega.

Cabeçalhos que não devem mais ser usados

CabeçalhoSituaçãoO que fazer
X-XSS-ProtectionFora de qualquer especificação e obsoleto. A MDN avisa que o filtro pode criar falhas de XSS em sites que não as tinham (MDN)Não enviar, ou enviar 0 para desligar o filtro, como sugere a OWASP; proteger com CSP
Expect-CTSó o Chromium implementou, e ele o considera obsoleto desde a versão 107, porque já exige Certificate Transparency por padrão (MDN)Remover
Feature-PolicyRenomeado para Permissions-Policy, com outra sintaxe. No Chrome funciona só como apelido, e a Permissions-Policy prevalece quando os dois vêm juntos (Chrome for Developers)Migrar para Permissions-Policy
Public-Key-PinsA OWASP recomenda não usar e remover de produção (OWASP)Remover

Um conjunto inicial completo

Um exemplo para um site servido dinamicamente, sem incorporação por outros sites e com pagamento em pop-up. A forma de configurar depende do servidor (nginx, Apache), do CDN ou do framework; o conteúdo dos cabeçalhos é o mesmo.

Strict-Transport-Security: max-age=63072000; includeSubDomains
Content-Security-Policy: script-src 'nonce-{gerado por resposta}' 'strict-dynamic'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'; report-to csp
Reporting-Endpoints: csp="https://exemplo.com.br/csp-relatorios"
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
X-Frame-Options: DENY
Cross-Origin-Opener-Policy: same-origin-allow-popups

Para comparar, o OWASP Secure Headers Project publica uma lista mais rígida e atualizada com frequência, pensada como referência máxima e não como configuração para copiar sem testar (headers_add.json).

Como verificar o seu site

No terminal, curl -sI https://exemplo.com.br/ mostra os cabeçalhos de uma resposta. Repita para uma página interna, um arquivo de imagem e uma resposta de erro, porque servidores e CDNs nem sempre aplicam os mesmos cabeçalhos em tudo. O HTTP Observatory da Mozilla dá uma nota e explica cada item. A auditoria do WebVyze aponta a falta de HSTS, CSP, X-Content-Type-Options e Referrer-Policy, a CSP que existe mas não barra scripts injetados e a página que pode ser embutida por outros sites, cada uma com o guia de correção. Em lojas, a CSP da página de pagamento também conta para o PCI DSS; o artigo sobre os requisitos 6.4.3 e 11.6.1 explica como, e os planos pagos do WebVyze mantêm um inventário dos scripts das páginas de checkout. O WebVyze só lê páginas públicas e não altera nada no site.

Perguntas frequentes

Posso colocar a CSP numa meta tag em vez de no cabeçalho?
Pode, com limites. A especificação ignora as diretivas frame-ancestors, report-uri e sandbox quando a política vem de uma meta tag, e o modo somente relatório (Content-Security-Policy-Report-Only) não funciona em meta tag. Para uma política completa, use o cabeçalho.
Os cabeçalhos precisam estar em todas as respostas ou só nas páginas HTML?
Depende do cabeçalho. O ASVS 5.0 pede HSTS, nosniff e frame-ancestors em todas as respostas e o Cross-Origin-Opener-Policy nas respostas que abrem um documento, como as páginas HTML. Configurar no servidor ou no CDN para todas as respostas costuma ser o caminho mais simples.
Remover os cabeçalhos Server e X-Powered-By melhora a segurança?
Dificulta a identificação da tecnologia usada, e a OWASP recomenda remover ou deixar esses cabeçalhos sem informação útil. Não impede que alguém descubra a tecnologia por outros meios e não dispensa as atualizações.
Como receber os relatórios de violação da CSP?
O navegador envia um POST em JSON para o endereço declarado em Reporting-Endpoints (diretiva report-to) ou em report-uri. Você precisa de um endpoint que aceite e guarde esses envios: um serviço próprio simples ou uma ferramenta de terceiros.
Sobre o autor

Daniel Paz

Especialista em WordPress, performance e SEO, fundador da WebOption

Daniel Paz é especialista em WordPress, performance e SEO, fundador da WebOption e palestrante internacional. Com mais de 18 anos de experiência em desenvolvimento web, ajuda empresas a transformar sites em plataformas rápidas, eficientes e orientadas a resultados.

Veja o que o seu site precisa corrigir.

Checagem grátis por lei, com a causa e o guia de correção de cada problema.

Checar meu site grátisCriar conta grátis

Continue lendo

Parceiros

Benefícios de parceiros com o mesmo cupom.

WPLIGHT

Links de parceiros. Podemos receber uma comissão, sem custo adicional para você.