Content Security Policy e headers de segurança: como reduzir riscos no navegador
Cabeçalhos de segurança são defesa de baixo custo e alto valor. Veja quais aplicar e como evitar quebrar a aplicação.
Cabeçalhos de segurança são uma das defesas de melhor custo-benefício em aplicações web. Eles instruem o navegador a se comportar de forma mais restrita, reduzindo o impacto de classes inteiras de ataque, como XSS, clickjacking e downgrade de conexão. O destaque é a Content Security Policy, ou CSP, que controla de onde o navegador pode carregar recursos e é a defesa em profundidade mais eficaz contra XSS.
Este guia trata dos principais cabeçalhos de segurança de forma defensiva: o que cada um faz, como construir uma CSP eficaz com nonce e hashes, como aplicar os demais cabeçalhos sem quebrar a aplicação e quais são suas limitações. O foco é ganhar proteção real no navegador, entendendo que cabeçalhos complementam, mas não substituem, a correção da aplicação.
Content Security Policy
A CSP define de onde scripts, estilos, imagens e outros recursos podem ser carregados. Bem configurada, ela limita o impacto de um XSS, porque mesmo que um atacante injete um script, o navegador se recusa a executá-lo se a origem não estiver permitida. O desafio é que uma CSP restrita pode quebrar a aplicação se houver scripts inline ou recursos de terceiros não previstos.
A prática recomendada é começar em modo de report, que apenas registra violações sem bloquear, analisar o que a aplicação realmente carrega e então endurecer a política gradualmente. Evite o uso amplo de permissões inseguras que esvaziam o valor da CSP, como liberar execução de scripts inline sem restrição, e prefira políticas específicas por tipo de recurso.
Construindo uma CSP eficaz com nonce e hashes
Uma CSP forte não depende de liberar scripts inline de forma ampla, que é justamente o que enfraquece a política contra XSS. Duas técnicas resolvem o problema dos scripts legítimos inline sem abrir a porta. O nonce é um valor aleatório, gerado a cada resposta, que o servidor coloca tanto no cabeçalho quanto na tag do script legítimo; o navegador só executa o inline que carrega o nonce correto. O hash permite autorizar um script inline específico pelo seu resumo criptográfico, útil quando o conteúdo é fixo.
Content-Security-Policy:
default-src 'self';
script-src 'self' 'nonce-VALOR_ALEATORIO';
object-src 'none';
base-uri 'self';
frame-ancestors 'none';
report-to csp-endpointAlgumas diretivas merecem atenção especial. A object-src com valor none bloqueia plugins legados que ampliam a superfície; a base-uri restrita impede que um atacante altere a base de resolução de URLs da página; e a frame-ancestors substitui o antigo X-Frame-Options para controlar quem pode enquadrar a página. Para receber relatórios de violação de forma estruturada, use a diretiva de report em conjunto com um endpoint que colete os eventos, o que orienta o endurecimento com base em dados reais.
Os demais cabeçalhos essenciais
Além da CSP, um conjunto de cabeçalhos eleva o piso de segurança com pouco esforço. O HSTS força HTTPS e evita downgrade; X-Content-Type-Options impede que o navegador adivinhe o tipo de conteúdo; a diretiva frame-ancestors da CSP, ou o X-Frame-Options em navegadores antigos, previne clickjacking; Referrer-Policy controla o vazamento de URL em referências; e Permissions-Policy restringe recursos do navegador como câmera e geolocalização.
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), camera=(), microphone=()O HSTS exige cuidado com o alcance. A diretiva de subdomínios aplica a política a todos eles, e a inclusão na lista de preload dos navegadores é difícil de reverter, então habilite ambas apenas quando tiver certeza de que todos os subdomínios servem HTTPS. Um max-age generoso é o esperado em produção, mas comece com um valor menor ao validar, para não travar um subdomínio esquecido que ainda dependa de HTTP.
- CSP com nonce ou hash: controla origens de recursos e mitiga XSS em profundidade
- HSTS: força HTTPS e evita downgrade, com cuidado em subdomínios e preload
- X-Content-Type-Options nosniff: impede sniffing de tipo de conteúdo
- frame-ancestors ou X-Frame-Options: previne clickjacking
- Referrer-Policy: limita vazamento de URL em referências
- Permissions-Policy: restringe recursos sensíveis do navegador
Cookies seguros e isolamento de origem
Os cabeçalhos de resposta não param na CSP. Os cookies de sessão precisam dos seus próprios atributos de segurança: Secure garante que só trafeguem por HTTPS, HttpOnly impede que o JavaScript os leia, o que reduz o valor de um XSS, e SameSite limita o envio entre origens, ajudando contra CSRF. Um cookie de sessão sem esses atributos é um alvo fácil e uma falha comum.
Set-Cookie: session=VALOR; Secure; HttpOnly; SameSite=Lax; Path=/Para aplicações que manipulam dados sensíveis ou usam recursos avançados do navegador, o isolamento de origem cruzada adiciona uma camada contra classes de ataque de canal lateral. Os cabeçalhos Cross-Origin-Opener-Policy e Cross-Origin-Resource-Policy separam o contexto da sua página de janelas e recursos de outras origens. Eles exigem teste, porque podem afetar integrações legítimas, mas endurecem o isolamento onde ele importa.
Onde aplicar e limitações
Os cabeçalhos podem ser aplicados na aplicação ou na borda, por exemplo no CloudFront ou no Cloudflare, o que facilita padronizar entre vários serviços. Aplicar na borda ajuda a garantir consistência, mas cabeçalhos que dependem de valor por resposta, como o nonce da CSP, precisam ser gerados pela aplicação, então às vezes a política vive nos dois lugares: uma base padronizada na borda e a parte dinâmica na aplicação.
Lembre que cabeçalhos são defesa em profundidade: eles reduzem o impacto de falhas, mas não corrigem a falha em si. Uma aplicação vulnerável a XSS continua vulnerável; a CSP apenas dificulta a exploração. Combine cabeçalhos com correção de código e testes, e revise a política sempre que adicionar um recurso de terceiro, porque cada novo script externo é uma decisão sobre a sua CSP.
Checklist prático
- Definir CSP e iniciar em modo de report
- Usar nonce ou hash para scripts inline legítimos, sem liberar inline de forma ampla
- Endurecer com object-src none, base-uri e frame-ancestors
- Configurar um endpoint de relatório de violações da CSP
- Analisar violações e endurecer a CSP gradualmente
- Habilitar HSTS com cuidado em subdomínios e preload
- Aplicar X-Content-Type-Options nosniff
- Definir Referrer-Policy e Permissions-Policy adequadas
- Marcar cookies de sessão com Secure, HttpOnly e SameSite
- Avaliar isolamento de origem cruzada em aplicações sensíveis
- Aplicar os cabeçalhos na borda para padronizar, com a parte dinâmica na aplicação
- Tratar cabeçalhos como defesa em profundidade, não correção
Boas práticas
- Comece a CSP em report e endureça com base em dados reais
- Prefira nonce e hash a liberar scripts inline de forma ampla
- Padronize cabeçalhos na borda quando possível
- Proteja os cookies de sessão com Secure, HttpOnly e SameSite
- Combine cabeçalhos com correção da aplicação
- Revise os cabeçalhos ao adicionar recursos de terceiros
- Teste o comportamento após cada endurecimento
Erros comuns
CSP que libera scripts inline de forma ampla
A política existe, mas não protege contra XSS na prática.
Subir CSP restrita direto, sem report
Quebra recursos legítimos e a equipe acaba afrouxando tudo.
HSTS com preload sem todos os subdomínios em HTTPS
Um subdomínio que ainda dependa de HTTP fica inacessível e é difícil reverter.
Cookies de sessão sem Secure, HttpOnly e SameSite
A sessão fica exposta a roubo por script e a envio indevido entre origens.
Tratar cabeçalhos como correção de vulnerabilidade
A falha permanece; os cabeçalhos só dificultam a exploração.
Cabeçalhos inconsistentes entre serviços
Alguns endpoints ficam desprotegidos por falta de padronização.
Quando procurar apoio especializado
Definir uma CSP eficaz sem quebrar a aplicação e padronizar cabeçalhos é parte dos serviços de Segurança de Aplicações e de WAF e Proteção de Borda da GUARDIASEC, que avaliam o comportamento no navegador e ajustam a configuração.
Perguntas frequentes
A CSP elimina o risco de XSS?
Não elimina, mas reduz bastante o impacto. A CSP é defesa em profundidade: mesmo que um XSS seja injetado, o navegador se recusa a executar scripts de origens não permitidas, dificultando a exploração. A correção da falha na aplicação continua necessária. A CSP é uma camada poderosa, não um substituto para código seguro.
Por que começar a CSP em modo de report?
Porque uma CSP restrita pode bloquear recursos legítimos que a aplicação carrega, especialmente scripts inline e conteúdo de terceiros. O modo de report registra violações sem bloquear, permitindo mapear o que a aplicação realmente usa antes de endurecer. Subir uma política restrita direto costuma quebrar a aplicação e levar a equipe a afrouxar tudo.
Qual a diferença entre usar nonce e hash na CSP?
O nonce é um valor aleatório gerado a cada resposta, que o servidor coloca no cabeçalho e na tag do script legítimo; o navegador só executa o inline que carrega o nonce certo. É indicado para conteúdo que muda. O hash autoriza um script inline específico pelo seu resumo criptográfico, o que serve para conteúdo fixo. Ambos evitam liberar scripts inline de forma ampla, que é o que enfraquece a política contra XSS.
Onde devo aplicar os cabeçalhos de segurança?
Podem ser aplicados na aplicação ou na borda, como CloudFront ou Cloudflare. A borda facilita padronizar os cabeçalhos entre vários serviços, mas valores que variam por resposta, como o nonce da CSP, precisam vir da aplicação. Na prática, uma base padronizada na borda somada à parte dinâmica na aplicação costuma ser o arranjo mais confiável.
HSTS com preload é sempre recomendado?
Não sem cuidado. A inclusão na lista de preload dos navegadores força HTTPS para o domínio e seus subdomínios e é difícil de reverter. Só habilite preload e a diretiva de subdomínios quando tiver certeza de que todos os subdomínios servem HTTPS. Comece com um max-age menor ao validar e aumente depois, para não travar um subdomínio esquecido que dependa de HTTP.
Cabeçalhos de segurança substituem o pentest?
Não. Cabeçalhos são defesa em profundidade que reduz o impacto de certas falhas, mas não corrigem vulnerabilidades da aplicação. Um pentest avalia o comportamento real e encontra falhas que os cabeçalhos apenas mitigam. O ideal é combinar cabeçalhos bem configurados com correção de código e testes de segurança regulares.
Guias relacionados
Próximo passo
Vamos avaliar os riscos do seu ambiente?
Conte seu cenário e definimos juntos o escopo certo. O objetivo é reduzir caminhos prováveis de ataque e elevar a maturidade de segurança, sem promessas absolutas.