CSP report-only: testando políticas antes de aplicar
1. O que é o Modo Report-Only do CSP?
Content Security Policy (CSP) é uma camada de segurança que ajuda a detectar e mitigar ataques como Cross-Site Scripting (XSS) e data injection. O modo padrão (Content-Security-Policy) bloqueia recursos que violam a política definida. Já o modo report-only (Content-Security-Policy-Report-Only) não bloqueia nada — ele apenas gera relatórios de violação.
A diferença fundamental é:
Content-Security-Policy: bloqueia violações e envia relatórios (se configurado)Content-Security-Policy-Report-Only: não bloqueia violações, apenas envia relatórios
Isso torna o modo report-only ideal para:
- Transição gradual de políticas em produção
- Validação de novas diretivas antes de aplicá-las
- Ambientes de staging e QA
- Identificação de dependências não documentadas de terceiros
2. Configurando o Header Content-Security-Policy-Report-Only
Sintaxe básica via cabeçalho HTTP
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-reports
Equivalente em meta tag HTML
<meta http-equiv="Content-Security-Policy-Report-Only" content="default-src 'self'; report-uri /csp-reports">
Diferenças práticas entre header e meta tag
| Aspecto | Header HTTP | Meta Tag |
|---|---|---|
| Controle | Servidor (mais seguro) | Página HTML |
| Aplicação | Todas as páginas | Apenas a página atual |
Suporte a report-to |
Sim | Não |
| Prioridade | Sobrescreve meta tag | Ignorada se header existir |
Recomendação: use sempre o cabeçalho HTTP quando possível, pois oferece mais controle e segurança.
3. Definindo o Endpoint de Reporte com report-uri e report-to
report-uri (legado)
Content-Security-Policy-Report-Only: default-src 'self'; report-uri https://meusite.com/csp-reports
report-to (moderno, baseado na Reporting API)
Content-Security-Policy-Report-Only: default-src 'self'; report-to csp-endpoint
E no cabeçalho Reporting-Endpoints:
Reporting-Endpoints: csp-endpoint="https://meusite.com/reports"
Estrutura JSON de um relatório de violação CSP
{
"csp-report": {
"document-uri": "https://exemplo.com/pagina",
"violated-directive": "script-src 'self'",
"blocked-uri": "https://cdn.malicioso.com/script.js",
"source-file": "https://exemplo.com/pagina",
"line-number": 42,
"column-number": 10,
"effective-directive": "script-src",
"original-policy": "default-src 'self'; report-uri /csp-reports"
}
}
Endpoint simples em Node.js para receber relatórios
const express = require('express');
const app = express();
app.use(express.json({ type: 'application/csp-report' }));
app.post('/csp-reports', (req, res) => {
const report = req.body['csp-report'];
console.log('Violação CSP detectada:', {
documento: report['document-uri'],
diretiva: report['violated-directive'],
recurso: report['blocked-uri']
});
res.status(204).end();
});
app.listen(3000);
4. Analisando Relatórios de Violação no Modo Report-Only
Campos essenciais do relatório
document-uri: URL da página onde a violação ocorreuviolated-directive: Diretiva CSP que foi violadablocked-uri: URL do recurso que foi bloqueadosource-file: Arquivo JavaScript que causou a violação (se aplicável)line-numberecolumn-number: Localização exata no código
Exemplo de análise prática
Suponha que você receba este relatório:
{
"csp-report": {
"document-uri": "https://loja.com/produtos",
"violated-directive": "img-src 'self'",
"blocked-uri": "https://cdn.analytics.com/tracker.gif"
}
}
Isso indica que sua página de produtos está tentando carregar imagens de um CDN de analytics não autorizado. Você precisará adicionar https://cdn.analytics.com à diretiva img-src.
Ferramentas de agregação
- report-uri.io: serviço gerenciado para receber e visualizar relatórios CSP
- Sentry: suporte a CSP reports com agregação e alertas
- Dashboard customizado: usando banco de dados (ex.: MongoDB) e visualização (ex.: Grafana)
Como diferenciar falsos positivos
- Extensões de navegador (ad-blockers, plugins) podem gerar relatórios falsos
- Teste em múltiplos navegadores para confirmar violações reais
- Verifique se o recurso bloqueado é essencial para o funcionamento da página
5. Iterando e Ajustando a Política com Base nos Relatórios
Estratégia de refinamento
- Comece restritivo:
default-src 'self' - Analise relatórios por 3-7 dias
- Adicione exceções apenas quando necessário
Exemplo prático: ajustando script-src
Relatório recebido:
{
"csp-report": {
"violated-directive": "script-src 'self'",
"blocked-uri": "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"
}
}
Ajuste na política:
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' https://cdnjs.cloudflare.com; report-uri /csp-reports
Identificando dependências de terceiros não documentadas
Relatórios podem revelar:
- Scripts de analytics que a equipe de marketing adicionou sem comunicar
- Fontes de terceiros carregadas por plugins ou widgets
- CDNs usadas por bibliotecas que você não sabia que estavam em uso
6. Transição do Modo Report-Only para o Modo Enforcement
Critérios para considerar uma política "madura"
- Zero violações legítimas por pelo menos 7 dias consecutivos
- Todos os recursos essenciais estão explicitamente permitidos
- Testes em múltiplos navegadores não mostram quebras
- Equipe de desenvolvimento validou que a política não afeta funcionalidades
Troca do cabeçalho
Antes (report-only):
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' https://cdnjs.cloudflare.com; report-uri /csp-reports
Depois (enforcement):
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdnjs.cloudflare.com; report-uri /csp-reports
Manutenção contínua
Mesmo no modo enforcement, mantenha um endpoint de reporte ativo. Isso permite:
- Detectar novas violações causadas por mudanças no código
- Identificar tentativas de ataque (ex.: injeção de scripts)
- Monitorar a saúde da política ao longo do tempo
7. Boas Práticas e Armadilhas Comuns
Evitar sobrecarga de relatórios
- Amostragem: configure seu servidor para processar apenas 10% dos relatórios
- Limites de taxa: rejeite requisições excessivas do mesmo IP
- Filtragem: ignore relatórios de extensões de navegador conhecidas
Cuidado com políticas muito restritivas
Políticas excessivamente restritivas podem quebrar:
- Botões de compartilhamento social
- Players de vídeo incorporados
- Widgets de chat ao vivo
- Mapas interativos
Testar em múltiplos navegadores
Cada navegador implementa CSP com pequenas diferenças:
- Chrome: suporte completo, incluindo
report-to - Firefox: bom suporte, mas pode diferir em diretivas específicas
- Safari: suporte mais limitado, especialmente para
report-to
Checklist de boas práticas
1. Inicie sempre com Content-Security-Policy-Report-Only
2. Configure um endpoint de reporte funcional
3. Analise relatórios por pelo menos uma semana
4. Documente cada exceção adicionada à política
5. Teste em Chrome, Firefox e Safari
6. Mantenha o endpoint de reporte mesmo no modo enforcement
7. Revise a política a cada novo deploy ou mudança significativa
Referências
- Content Security Policy (CSP) - MDN Web Docs — Documentação oficial da Mozilla sobre CSP, incluindo modo report-only e sintaxe completa
- Content-Security-Policy-Report-Only - MDN HTTP Headers — Referência específica do cabeçalho report-only com exemplos
- CSP: report-uri - MDN Web Docs — Documentação da diretiva report-uri para configuração de endpoints
- Reporting API - W3C Specification — Especificação oficial da W3C para a API de relatórios, incluindo report-to
- CSP Evaluator - Google — Ferramenta online do Google para testar e validar políticas CSP
- Report URI - CSP Monitoring Service — Serviço gerenciado para receber, analisar e visualizar relatórios CSP
- CSP: A Complete Guide - Content Security Policy — Guia prático e abrangente sobre CSP com exemplos de configuração e boas práticas