HTTP Security Headers: Content-Security-Policy, HSTS, X-Frame-Options
1. Introdução aos HTTP Security Headers
Headers de segurança HTTP são a primeira linha de defesa contra ataques comuns em aplicações web modernas. Eles instruem o navegador a adotar comportamentos específicos que previnem explorações como Cross-Site Scripting (XSS), clickjacking e ataques man-in-the-middle (MITM). A ausência desses headers pode transformar uma aplicação segura em um alvo fácil.
Para inspecionar headers no navegador, utilize as DevTools (aba Network) ou ferramentas de linha de comando como cURL:
curl -I https://suaaplicacao.com
A resposta mostrará headers como content-security-policy, strict-transport-security e x-frame-options, que exploraremos em detalhes.
2. Content-Security-Policy (CSP): Blindando contra XSS
O header Content-Security-Policy define uma política de fontes confiáveis para scripts, estilos e outros recursos carregados pela página. Ele funciona como uma lista de permissões: qualquer recurso fora da lista é bloqueado pelo navegador.
Diretivas principais:
default-src: política padrão para todos os tipos de recursoscript-src: fontes permitidas para scripts JavaScriptstyle-src: fontes permitidas para folhas de estiloimg-src: fontes permitidas para imagens
Exemplo de CSP restritivo:
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' https://cdn.exemplo.com
Essa política permite apenas recursos do próprio domínio ('self'), exceto imagens que podem vir de um CDN específico. Scripts e estilos inline são bloqueados, eliminando vetores de XSS.
Para testar sem bloquear, use Content-Security-Policy-Report-Only:
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; report-uri /csp-report
Isso registra violações sem aplicar bloqueios, permitindo ajustes seguros.
3. CSP Avançado: Nonces, Hashes e Relatório de Violações
Para scripts inline dinâmicos (como os gerados por frameworks), use nonces — valores aleatórios gerados por requisição:
Content-Security-Policy: script-src 'nonce-abc123def456'
No HTML, o script inline recebe o mesmo nonce:
<script nonce="abc123def456">alert('Seguro!');</script>
Para scripts estáticos, utilize hashes SHA:
Content-Security-Policy: script-src 'sha256-ABC123...'
Configure o monitoramento de violações com report-uri (legado) ou report-to (moderno):
Content-Security-Policy: default-src 'self'; report-uri https://meuservidor.com/report
Content-Security-Policy: default-src 'self'; report-to csp-endpoint
Headers Report-To adicionais definem o endpoint real. Essa abordagem permite detectar tentativas de ataque em produção.
4. HTTP Strict Transport Security (HSTS): Forçando HTTPS
O header Strict-Transport-Security instrui o navegador a sempre usar HTTPS para o domínio, prevenindo ataques de downgrade como SSL stripping.
Parâmetros cruciais:
max-age: tempo (em segundos) que o navegador deve lembrar da políticaincludeSubDomains: aplica a política a todos os subdomíniospreload: permite inclusão em listas de pré-carregamento de navegadores
Exemplo prático:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Cuidados: Comece com max-age baixo (ex.: 300 segundos) para teste, depois aumente gradualmente. Um max-age muito alto em ambiente incorreto pode causar lockout — usuários não conseguirão acessar via HTTP mesmo em redes internas.
5. X-Frame-Options: Combatendo Clickjacking
O header X-Frame-Options controla se a página pode ser exibida em iframes. Diretivas:
DENY: bloqueia qualquer iframeSAMEORIGIN: permite apenas do mesmo domínioALLOW-FROM(obsoleto): permitia domínio específico (não use)
Exemplo:
X-Frame-Options: SAMEORIGIN
Para controle mais granular, prefira CSP frame-ancestors:
Content-Security-Policy: frame-ancestors 'self' https://app.externo.com
frame-ancestors é mais flexível e moderno, permitindo múltiplos domínios e substituindo X-Frame-Options. Se ambos forem usados, o CSP tem precedência em navegadores modernos.
Teste vulnerabilidade de clickjacking criando um HTML com iframe:
<iframe src="https://suaaplicacao.com" width="500" height="500"></iframe>
Se a página carregar, está vulnerável. Ferramentas como SecurityHeaders.com detectam automaticamente.
6. Headers Complementares: X-Content-Type-Options e Referrer-Policy
X-Content-Type-Options: nosniff previne MIME sniffing, forçando o navegador a respeitar o Content-Type declarado:
X-Content-Type-Options: nosniff
Referrer-Policy controla informações de referência enviadas em requisições:
Referrer-Policy: strict-origin-when-cross-origin
Essa política envia a URL completa apenas para origens seguras, e apenas a origem para origens inseguras.
Permissions-Policy (antiga Feature-Policy) restringe APIs sensíveis:
Permissions-Policy: geolocation=(), camera=(), microphone=()
Isso bloqueia acesso a geolocalização, câmera e microfone por padrão.
7. Implementação Prática e Boas Práticas
Exemplo de configuração para Nginx:
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-${request_id}'" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
Para Apache:
Header always set Content-Security-Policy "default-src 'self'; script-src 'self'"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-Frame-Options "SAMEORIGIN"
Checklist de deploy:
- Teste em staging com
Content-Security-Policy-Report-Only - Use
max-ageprogressivo para HSTS (300s → 86400s → 31536000s) - Verifique com SecurityHeaders.com e Mozilla Observatory
- Monitore relatórios de violação CSP
- Tenha plano de rollback (remover headers ou reduzir
max-age)
8. Erros Comuns e Mitigação
CSP muito permissivo: Evite 'unsafe-inline' e 'unsafe-eval'. Se necessário, use nonces ou hashes. Exemplo de CSP permissivo e perigoso:
Content-Security-Policy: default-src 'self' 'unsafe-inline' 'unsafe-eval' https://*
Isso anula a proteção contra XSS.
HSTS com max-age baixo: Valores como max-age=300 não protegem contra ataques persistentes. Aumente gradualmente até 31536000 (1 ano).
Conflito X-Frame-Options e frame-ancestors: Se ambos forem usados, frame-ancestors prevalece em navegadores modernos. Para consistência, use apenas CSP.
Sem monitoramento de violações: Configurar CSP sem report-uri ou report-to é como ter alarme sem sirene. Sempre colete relatórios para ajustar a política.
Referências
- Content Security Policy (CSP) - MDN Web Docs — Documentação completa sobre CSP, diretivas e exemplos práticos
- HTTP Strict Transport Security (HSTS) - MDN Web Docs — Guia detalhado sobre HSTS, parâmetros e pré-carregamento
- X-Frame-Options - MDN Web Docs — Especificação oficial e exemplos de uso
- SecurityHeaders.com — Ferramenta gratuita para analisar headers de segurança do seu site
- Mozilla Observatory — Scanner de segurança web que avalia headers e fornece recomendações
- OWASP HTTP Security Headers Cheat Sheet — Guia prático da OWASP com tabela de headers e configurações recomendadas
- Google Web Fundamentals: Security Headers — Artigo do Google sobre melhores práticas de headers de segurança