Toda resposta do seu site traz cabeçalhos HTTP (os headers) que o visitante nunca vê. Alguns deles são instruções de segurança para o navegador: carregue scripts só destes endereços, use HTTPS neste host, não deixe outros sites colocarem esta página num frame, mantenha este cookie longe do JavaScript. Quando eles faltam, o navegador volta aos padrões mais permissivos. Quando estão errados, o login ou o checkout da loja podem parar de funcionar.
Este guia mostra como ler os cabeçalhos que o seu site realmente envia, o que cada um faz e quais valores são seguros para começar. Ele traz uma configuração base para nginx, para o .htaccess do Apache, comum em hospedagem compartilhada, e para hospedagens estáticas como Cloudflare Pages e Netlify, além dos erros que deixam algumas respostas sem cabeçalhos. Todos os exemplos usam example.com.
Escopo deste guia
O snapshot gratuito lê os cabeçalhos de uma única resposta: a página inicial da origem que você digitar, depois de até cinco redirecionamentos. Ele verifica principalmente se cada cabeçalho está presente, não se os valores servem para o seu site, e não é um pentest.
1. Verifique os cabeçalhos você mesmo: DevTools e curl
No Chrome ou no Edge, abra o DevTools, vá ao painel Network e recarregue a página. Clique na primeira requisição (o documento HTML), abra a aba Headers e role até Response Headers. Se o DevTools estiver em português, esses nomes podem aparecer traduzidos. Marque Preserve log para manter as requisições entre carregamentos e redirecionamentos, e Disable cache para receber uma resposta nova em vez de uma cópia em cache (referência do painel Network do Chrome DevTools). O Monitor de rede do Firefox funciona do mesmo jeito.
No terminal, o curl mostra exatamente o que o servidor envia:
curl -sS -D - -o /dev/null https://example.com/Acrescente -L para seguir os redirecionamentos e ver os cabeçalhos de cada salto. No Windows, chame curl.exe e use -o NUL. O curl -I é mais curto, mas envia uma requisição HEAD em vez de GET, e algumas aplicações tratam HEAD por outro caminho no código; por isso, confirme com um GET o que você encontrar.
Repita a verificação para o endereço http:// (ele deve responder com um redirecionamento 301 ou 308 para HTTPS), para o outro nome do host (www ou o domínio sem www), para uma página que não existe, a página de login, uma resposta da API e um arquivo estático. A aplicação, o servidor web e a CDN muitas vezes colocam cabeçalhos diferentes em cada um desses casos, e só vale o que chega ao navegador.
2. O que cada cabeçalho faz e um valor seguro para começar
| Cabeçalho | O que faz | Valor inicial seguro |
|---|---|---|
| Content-Security-Policy | Limita de onde scripts, estilos, frames e outros recursos podem ser carregados | Uma política de rascunho, enviada primeiro como Content-Security-Policy-Report-Only |
| CSP frame-ancestors | Define quais sites podem incorporar a página num frame (defesa contra clickjacking) | frame-ancestors 'self' ou 'none' |
| X-Frame-Options | Controle de frames mais antigo, mantido como alternativa para navegadores antigos | SAMEORIGIN ou DENY, coerente com o frame-ancestors |
| Strict-Transport-Security | Diz ao navegador para usar só HTTPS neste host durante max-age segundos | max-age=300, aumentado por etapas |
| X-Content-Type-Options | Impede que o navegador adivinhe o tipo MIME; bloqueia scripts e folhas de estilo servidos com o tipo errado | nosniff |
| Referrer-Policy | Controla quanto da URL da página vai para outros sites no cabeçalho Referer | strict-origin-when-cross-origin |
| Permissions-Policy | Desliga recursos do navegador, como a câmera, para a página e os frames dela | camera=(), microphone=(), geolocation=() |
| Cross-Origin-Opener-Policy | Isola a sua janela de pop-ups de outras origens e da página que a abriu | same-origin, ou same-origin-allow-popups para pop-ups de login OAuth ou de pagamento |
| Atributos do Set-Cookie | Limitam como os cookies de sessão trafegam e quem pode lê-los | Secure; HttpOnly; SameSite=Lax |
| X-XSS-Protection | Controlava um filtro de navegadores antigos; hoje está obsoleto | Remova, ou envie 0 |
Com nosniff, o navegador confia no Content-Type declarado e bloqueia scripts e folhas de estilo que chegam com o tipo errado; por isso, confira esses tipos antes de ativá-lo. Sem um cabeçalho Referrer-Policy, os navegadores atuais já usam strict-origin-when-cross-origin; a OWASP ainda sugere enviá-lo de forma explícita por causa dos navegadores antigos, e no-referrer é mais restritivo se nada do que você usa depender do referrer. No Permissions-Policy, () desativa o recurso na página e em todos os frames dentro dela; libere um recurso só para a origem do widget que precisa dele. O COOP same-origin ajuda contra ataques de vazamento entre origens (XS-Leaks), mas pode quebrar pop-ups de login ou de pagamento servidos de outra origem, como a janela de checkout de um gateway de pagamento.
3. Content-Security-Policy e frame-ancestors
A CSP diz ao navegador de onde a página pode carregar scripts, estilos, imagens, frames e conexões. Ela limita o que um script injetado consegue fazer; não substitui o escape e a validação de entradas. O guia de CSP do MDN recomenda uma CSP estrita, baseada num nonce novo a cada resposta ou em hashes, em vez de uma longa lista de hosts permitidos. 'unsafe-inline' anula boa parte do objetivo, e o navegador o ignora em qualquer diretiva que também tenha um nonce ou hash. O que costuma dificultar uma política estrita é código de terceiros que carrega outros scripts, como gerenciadores de tags, pixels de anúncios e widgets de chat; por isso, anote o motivo de cada exceção que você acrescentar.
default-src serve de reserva (fallback) para as diretivas de busca, como script-src, mas não para o frame-ancestors: uma política com default-src 'none' ainda deixa qualquer site colocar a página num frame. Defina frame-ancestors 'self' de forma explícita, ou 'none', que é semelhante a X-Frame-Options: DENY (MDN). A OWASP HTTP Headers Cheat Sheet diz que o frame-ancestors torna o X-Frame-Options obsoleto nos navegadores que o suportam, enquanto o X-Frame-Options ainda cobre os navegadores antigos; se você enviar os dois, faça com que permitam o mesmo enquadramento. Duas armadilhas: o frame-ancestors, uma política report-only e o X-Frame-Options não têm efeito numa tag <meta>, e X-Frame-Options: ALLOW-FROM faz os navegadores modernos ignorarem o cabeçalho inteiro.
Um primeiro rascunho para um site sem scripts de terceiros é a política recomendada pelo OWASP Secure Headers Project:
default-src 'self'; form-action 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; upgrade-insecure-requestsEla bloqueia scripts e estilos inline e tudo o que vem de outros hosts, então espere muitos relatórios no começo; é por isso que ela entra primeiro como Report-Only (seção 8). Aproveite só a linha da CSP: o conjunto completo do projeto também traz valores como Cache-Control: no-store e Clear-Site-Data, que desativariam o cache e apagariam os cookies e os dados armazenados do visitante em toda resposta. Em respostas JSON de API, que o navegador não renderiza, a CSP faz pouca diferença.
4. HSTS: aumente o max-age aos poucos e pense duas vezes antes do preload
O Strict-Transport-Security diz ao navegador para usar só HTTPS no host e converter automaticamente as próximas requisições http://. O navegador ignora o cabeçalho quando ele chega por HTTP simples; por isso, envie-o nas respostas HTTPS, não no redirecionamento de HTTP para HTTPS. Sozinho, ele não protege a primeiríssima conexão de um visitante.
Planeje o custo: num host com HSTS, o visitante não consegue passar por cima de um erro de certificado, então um certificado vencido deixa sem acesso quem já visitou o site. Certificados TLS públicos emitidos desde 15 de março de 2026 podem valer no máximo 200 dias (CA/Browser Forum), e o Let’s Encrypt não envia mais e-mails de aviso de expiração; por isso, deixe a renovação automática e o seu próprio monitoramento de validade funcionando antes. O guia de certificado SSL/TLS e cabeçalhos de segurança trata da parte dos certificados.
Aumente o max-age (em segundos) por etapas, como recomenda o hstspreload.org, e veja se algo quebrou a cada passo: 300 (5 minutos), 604800 (1 semana), 2592000 (1 mês) e depois 31536000 (1 ano) ou 63072000 (2 anos, o valor que a OWASP usa). max-age=0 remove a política, mas só quando enviado por HTTPS e só para os visitantes que voltarem e o receberem. Acrescente includeSubDomains quando todos os subdomínios funcionarem por HTTPS, e faça cada subdomínio enviar também o próprio cabeçalho.
O preload embute o seu domínio nos navegadores, para que até a primeira visita use HTTPS. O site de inscrição, hstspreload.org, agora recomenda o HSTS, mas não o preload: Chrome e Safari já convertem navegações HTTP em HTTPS, então o preload acrescenta pouco, e uma remoção da lista leva meses para chegar aos usuários. A OWASP HTTP Headers Cheat Sheet ainda inclui preload no cabeçalho de exemplo, enquanto o valor recomendado pelo OWASP Secure Headers Project o deixa de fora. Não o acrescente por padrão nem o copie de um modelo pronto; tutoriais e traduções mais antigos podem não refletir essa mudança, então confira a data da fonte.
6. Cabeçalhos para remover: X-XSS-Protection e outras sobras
- X-XSS-Protection ativava um filtro em navegadores antigos que podia, ele mesmo, criar vulnerabilidades de XSS (MDN). A OWASP recomenda não enviá-lo, ou desativá-lo com
0; a CSP é a substituta. - Expect-CT: a OWASP recomenda não usá-lo e, citando a Mozilla, removê-lo das configurações existentes.
- Public-Key-Pins (HPKP) foi removido do Chromium em 2018 e não é suportado por nenhum navegador moderno.
- Feature-Policy foi substituído pelo Permissions-Policy.
Os cabeçalhos Server e X-Powered-By revelam o software que você usa, às vezes com o número da versão. A OWASP sugere removê-los ou deixá-los sem informação útil, mas o próprio guia de testes da OWASP chama isso de segurança por obscuridade, e o MDN diz que manter o software atualizado importa mais. Tire os números de versão (no nginx, server_tokens off; remove a versão, não o cabeçalho) e invista o esforço em atualizações.
7. Uma configuração base para nginx, Apache e hospedagens estáticas
Esta base para nginx define os cabeçalhos de baixo risco, começa o HSTS e a CSP nas fases de teste e redireciona HTTP para HTTPS no mesmo host. O parâmetro always acrescenta os cabeçalhos também às respostas de erro.
server {
listen 80;
server_name example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
# ssl_certificate e ssl_certificate_key entram aqui
server_tokens off;
add_header Strict-Transport-Security "max-age=300" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Cross-Origin-Opener-Policy "same-origin" always;
add_header Content-Security-Policy-Report-Only "default-src 'self'; form-action 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'self'" always;
}Dois comportamentos documentados do módulo de cabeçalhos do nginx explicam muitos cabeçalhos ausentes. Sem always, o add_header vale só para os códigos 200, 201, 204, 206, 301, 302, 303, 304, 307 e 308, então as páginas 404 e 500 saem sem os cabeçalhos. E as diretivas add_header só são herdadas do nível de cima se o nível atual não definir nenhuma: um único add_header dentro de um bloco location derruba ali todos os cabeçalhos de segurança definidos no server. Repita os cabeçalhos, use include com um arquivo compartilhado ou, a partir do nginx 1.29.3, use add_header_inherit merge;.
Em hospedagem compartilhada com Apache, os cabeçalhos costumam ir no arquivo .htaccess. Segundo a documentação do mod_headers, a diretiva Header é aceita nesse arquivo quando a hospedagem libera esse tipo de configuração (AllowOverride FileInfo), e a condição always faz o cabeçalho sair também nas respostas de erro:
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Content-Security-Policy-Report-Only "default-src 'self'; form-action 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'self'"Depois de salvar, confira o resultado com curl. Se o CMS ou um plugin de segurança também definir algum desses cabeçalhos, ele pode sair duplicado; escolha uma camada só para cada cabeçalho.
Hospedagens estáticas como Cloudflare Pages e Netlify leem um arquivo _headers publicado junto com o site. Este exemplo segue o formato documentado pela Cloudflare, que a Netlify também usa:
/*
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
X-Frame-Options: SAMEORIGIN
Content-Security-Policy-Report-Only: default-src 'self'; form-action 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'self'Conheça os limites. O Cloudflare Pages não aplica o arquivo às respostas geradas por Pages Functions, aceita até 100 regras de cabeçalho com no máximo 2.000 caracteres por linha e junta os valores com vírgula quando o mesmo cabeçalho é aplicado duas vezes. A Netlify só aplica cabeçalhos personalizados aos arquivos que ela mesma serve, não a conteúdo via proxy, functions, edge functions ou páginas renderizadas no servidor; essas respostas precisam definir os próprios cabeçalhos. O HSTS ficou fora dos exemplos do Apache e das hospedagens estáticas: veja com curl o que a plataforma já envia antes de acrescentá-lo.
8. Implante por etapas e evite os erros comuns
- Acrescente nosniff, Referrer-Policy, Permissions-Policy e a proteção contra frames e, em seguida, teste login, checkout e widgets incorporados.
- Envie a CSP de rascunho como
Content-Security-Policy-Report-Only. Nada é bloqueado; as violações aparecem no console do navegador e, se a política indicar um, num endpoint de relatórios. Percorra as jornadas principais, incluindo as páginas atrás do login, e ajuste a política. - Comece o HSTS com um
max-agecurto e aumente por etapas. - Passe a aplicar a CSP de verdade. Uma política Report-Only mais restrita pode rodar ao lado dela para testar a próxima rodada de restrições.
- Rode de novo as verificações com curl depois de cada mudança no servidor, na CDN ou no framework.
Erros comuns:
- Cabeçalhos só em algumas respostas. A página inicial tem; a página 404, a API, os arquivos estáticos ou uma página de login servida separadamente não têm.
- Trocar host e protocolo num único redirecionamento. Se
http://example.comredireciona direto parahttps://www.example.com, o navegador nunca recebe o HSTS deexample.com. Redirecione primeiro para HTTPS no mesmo host, envie o HSTS nessa resposta HTTPS e só então redirecione para owww. - A CDN sobrescreve a origem. Uma CDN ou um proxy podem acrescentar, trocar, remover ou duplicar cabeçalhos. Defina qual camada é dona de cada cabeçalho e confirme o resultado com curl.
- Uma CSP que libera tudo. Uma política recheada de
'unsafe-inline','unsafe-eval'ou*para silenciar erros passa numa verificação de presença, mas bloqueia pouco. - includeSubDomains cedo demais. Um subdomínio esquecido que só funciona por HTTP fica inacessível para os navegadores que armazenaram a política.
Cabeçalhos são uma camada. O checklist de lançamento de site coloca os cabeçalhos ao lado de DNS, TLS e redirecionamentos, e o guia de auditoria de segurança de site cobre login, permissões e uma rotina de revisão que pode ser repetida.
9. Como o snapshot gratuito do Sitelemetry verifica os cabeçalhos
O snapshot gratuito de prontidão para lançamento roda oito verificações passivas em uma origem pública, sem cadastro; uma delas lê os cabeçalhos de segurança HTTP. Ele não é um pentest nem a auditoria das seis áreas.
- Ele requisita a página inicial da origem que você digitar (caminhos e query strings são descartados), segue até cinco redirecionamentos e avalia a resposta final. Nenhuma outra página é requisitada.
- Ele verifica principalmente a presença. CSP ausente, HSTS ausente num endereço HTTPS, falta de proteção contra frames e
Access-Control-Allow-Origin: *são classificados como médios. X-Content-Type-Options diferente denosniff, Referrer-Policy ausente e qualquer cabeçalhoServerouX-Powered-Bysão classificados como baixos; assim,Server: nginxsem versão ainda gera um sinal baixo. Cookies definidos nessa resposta sem HttpOnly, ou sem Secure em HTTPS, são classificados como médios; o SameSite não é verificado. - Uma nota de blindagem separada (de A a F) pontua os cabeçalhos presentes junto com o resultado do TLS e dá menos crédito à CSP quando ela permite
'unsafe-inline'(ou'unsafe-eval'para scripts). Permissions-Policy e COOP contam só nessa nota. - A verificação separada de redirecionamento HTTPS depende do que você digita. Para um domínio sem protocolo ou um endereço
https://, ela aponta como baixo ummax-agedo HSTS abaixo de 180 dias, o que é esperado durante o aumento gradual, e procura referênciashttp://no HTML da página (conteúdo misto); ela não testa o redirecionamento de HTTP para HTTPS. O redirecionamento só é testado quando você digita o endereçohttp://, e essa execução pula a verificação de TLS e não aponta HSTS ausente.
O resultado mostra uma pontuação, a nota de blindagem, o número de sinais de risco e de verificações aprovadas e até três sinais, com os riscos primeiro. Ele não lista cada cabeçalho e o seu valor; para isso, e para as respostas que o snapshot não requisita, use o DevTools ou o curl.
Perguntas frequentes
Como verificar os cabeçalhos de segurança do meu site?
No DevTools do navegador, abra o painel Network, recarregue a página, selecione o documento HTML e leia os Response Headers. No terminal, o comando curl -sS -D - -o /dev/null https://example.com/ mostra os cabeçalhos. Verifique também o endereço http://, uma página 404, uma resposta da API e um arquivo estático, porque os cabeçalhos costumam mudar entre eles.
Quais cabeçalhos de segurança HTTP devo configurar primeiro?
Comece por X-Content-Type-Options: nosniff, Referrer-Policy, Permissions-Policy e a proteção contra frames, que são os que menos costumam quebrar alguma coisa; mesmo assim, teste scripts, login e widgets incorporados depois. Em seguida, teste uma Content-Security-Policy em modo Report-Only e aumente o max-age do HSTS por etapas.
Ainda devo enviar o X-XSS-Protection?
Não. Remova o cabeçalho ou envie X-XSS-Protection: 0 e conte com uma Content-Security-Policy. O antigo filtro de navegador que ele controlava podia, ele mesmo, criar vulnerabilidades de XSS.
Preciso do X-Frame-Options se já uso frame-ancestors?
A diretiva frame-ancestors da CSP o substitui nos navegadores que a suportam. X-Frame-Options: DENY ou SAMEORIGIN continua sendo uma alternativa razoável para navegadores antigos, desde que os dois cabeçalhos permitam o mesmo enquadramento. Não use ALLOW-FROM: os navegadores modernos ignoram o cabeçalho inteiro quando o encontram.
Devo colocar meu domínio na lista de preload do HSTS?
Normalmente, não. O próprio site de inscrição, hstspreload.org, agora recomenda o HSTS, mas não o preload, porque Chrome e Safari já convertem navegações HTTP em HTTPS. Uma remoção da lista também leva meses para chegar aos usuários.
Cabeçalhos de segurança deixam meu site seguro?
Não sozinhos. Eles limitam o estrago de scripts injetados, clickjacking, rebaixamento de protocolo e roubo de cookies. Não corrigem código vulnerável, software desatualizado nem controle de acesso fraco.
Fontes e leituras
- MDN: guia de Content Security Policy (CSP)developer.mozilla.org
- MDN: diretiva frame-ancestors da CSPdeveloper.mozilla.org
- MDN: cabeçalho Strict-Transport-Securitydeveloper.mozilla.org
- MDN em português: Strict-Transport-Securitydeveloper.mozilla.org
- MDN em português: Content-Security-Policydeveloper.mozilla.org
- MDN: cabeçalho Set-Cookie e atributos de cookiedeveloper.mozilla.org
- OWASP HTTP Headers Cheat Sheetcheatsheetseries.owasp.org
- OWASP Secure Headers Project: valores recomendadosraw.githubusercontent.com
- HSTS Preload List Submissionhstspreload.org
- nginx: ngx_http_headers_module (add_header)nginx.org
- Apache HTTP Server: mod_headershttpd.apache.org
- Cloudflare Pages: Headersdevelopers.cloudflare.com
- Netlify: Custom headersdocs.netlify.com
Preparado pela equipe editorial do Sitelemetry. Consulte as fontes indicadas para aprofundar o assunto.



