Uma Content Security Policy (CSP) é um cabeçalho de resposta HTTP que informa ao navegador de que origens uma página pode carregar scripts, estilos, imagens e ligações. Tudo o que não estiver nessa lista de permissões é bloqueado antes de ser executado. Normalizada pelo W3C, a CSP é a principal defesa nativa do navegador contra cross-site scripting (XSS) e injeção de scripts.
TL;DR: o que é a CSP
- O CSP funciona através da declaração de uma lista de permitidos por tipo de recurso (script-src, img-src, connect-src, etc.). Tudo o que não estiver na lista é bloqueado pelo navegador antes de ser executado.
- É entregue como um cabeçalho de resposta HTTP ou uma tag
<meta>no<head>da página, e o modo Report-Only permite testar uma política sem quebrar o site. - O CSP é uma base, não uma defesa completa. Controla de onde um script é carregado, não o que o script faz depois de executar, por isso um domínio comprometido mas permitido continua a ser executado.
- Só o CSP não é suficiente para a conformidade com o PCI DSS 4.0.1. O requisito §6.4.3 exige inventário e autorização de scripts; o §11.6.1 exige deteção de adulteração. Ambos vão além do que o CSP consegue impor, especialmente contra um domínio permitido comprometido, como no incidente do Polyfill.io em 2024.
O que significa CSP?
CSP significa Content Security Policy (Política de Segurança de Conteúdo). É um cabeçalho de resposta HTTP (também configurável através de uma tag <meta> no <head> da página) que indica ao navegador quais as fontes de scripts, estilos, imagens e ligações que uma página pode carregar, bloqueando tudo o que não esteja nessa lista de permitidos antes de ser executado.
Compreender a Content Security Policy (CSP)
Content Security Policy (CSP) é uma funcionalidade de segurança do navegador que foi implementada para mitigar certos tipos de ataques baseados no navegador, como o cross-site scripting. O CSP foi normalizado pelo World Wide Web Consortium (W3C) na especificação CSP Level 3, e permite que um site envie um conjunto de regras (através de cabeçalhos de resposta HTTP ou tags <meta> dentro do <head> do HTML) que indicam ao navegador quais as fontes de conteúdo permitidas.
Estas regras, chamadas diretivas, especificam origens aprovadas para scripts, imagens, estilos, iframes e muito mais. O objetivo principal de usar o CSP é ter controlo total sobre de onde os scripts são carregados, além de controlar quais os scripts que uma página tem permissão para executar, tentando assim impedir que scripts injetados ou não autorizados sejam executados.
Por exemplo, uma diretiva CSP pode indicar que os scripts só devem ser carregados a partir do próprio domínio do site (usando ‘self’), ou a partir de domínios específicos considerados fiáveis. O navegador irá então bloquear qualquer ficheiro de script ou script inline que não venha de uma fonte permitida. Isto defende contra ataques XSS, em que um atacante tenta injetar tags <script> ou código malicioso num site. Atualmente, a maioria dos navegadores também suporta o modo ‘Report-only’ do CSP. Isto permite aos programadores testar uma política em segurança. Quando ativado, as violações da política são registadas num endpoint de relatórios em vez de serem bloqueadas de imediato. Esta é uma boa prática ao implementar o CSP pela primeira vez.
Como funciona a Content Security Policy (CSP)
Uma Content Security Policy é entregue ao navegador através do cabeçalho de resposta HTTP chamado Content-Security-Policy, ou através de uma tag meta no <head> do HTML. A política é composta por diretivas separadas por ponto e vírgula, e cada diretiva controla um tipo específico de recurso.
- ‘script-src’ self: permite scripts apenas a partir da mesma origem. Qualquer
<script>de outro domínio (ou código de script inline) é bloqueado pelo navegador. - ‘connect-src’ self https://api.domain.com : permite chamadas AJAX/XHR/fetch apenas para o mesmo site, ou para o domínio fiável api.domain.com. Isto impede que código malicioso exfiltre dados para servidores desconhecidos a partir do site.
- img-src ‘self’ data: pode ser usado para carregar imagens apenas a partir do mesmo site e bloquear imagens externas - o que pode ser usado para prevenir fugas de dados através de pedidos de imagem.
Nonces e hashes do CSP
O CSP também suporta mecanismos avançados como nonces (‘nonce-abc123’) e hashes (‘sha256-xyz…’). Estes permitem que scripts inline sejam executados em segurança, provando criptograficamente a sua integridade. Em vez de proibir todo o código inline, os programadores podem autorizar seletivamente scripts específicos. Isto melhora a flexibilidade sem sacrificar a segurança.
Existem imensas outras diretivas que podem ser usadas para outros tipos de dados, como media, fontes, iframes, etc., mas a ideia central de usar uma Content Security Policy é incluir na lista de permitidos as fontes fiáveis. Quando o navegador carrega uma página e verifica que conteúdo deve carregar, consulta primeiro o CSP e aplica estas regras em cada carregamento. Qualquer script ou recurso que viole esta política não será carregado. Para um guia de implementação detalhado, consulte a CSP Cheat Sheet da OWASP.
Diretivas comuns do CSP e a sua finalidade
| Diretiva | Finalidade | Caso de uso típico |
|---|---|---|
default-src | Define uma política base para todos os recursos quando nenhuma outra regra se aplica. | Comece de forma restritiva: default-src 'none'; |
script-src | Controla quais as fontes de JavaScript permitidas. | Inclua na lista de permitidos 'self', CDNs, ou use scripts baseados em nonce/hash. |
style-src | Limita de onde o CSS pode ser carregado. | Use 'self'; evite 'unsafe-inline' sempre que possível. |
img-src | Define fontes de imagem fiáveis. | Previne fugas de dados através de chamadas de imagem externas. |
connect-src | Restringe destinos de AJAX, fetch e WebSocket. | Bloqueia a exfiltração de dados para domínios desconhecidos. |
frame-ancestors | Especifica quais os sites que podem incorporar as suas páginas em iframes. | Previne clickjacking: frame-ancestors 'none'; |
report-uri / report-to | Define para onde são enviados os relatórios de violação do CSP. | Regista e analisa violações do CSP para afinar a política. |
Exemplos de cabeçalhos CSP que pode copiar hoje
Seguem-se pontos de partida prontos a copiar para as implementações de CSP mais comuns. Teste primeiro no modo Content-Security-Policy-Report-Only, observe os relatórios em busca de scripts legítimos que seriam bloqueados, e só depois passe para o modo de aplicação.
1. Política inicial estrita (negar por defeito + lista de permitidos)
Content-Security-Policy:
default-src 'none';
script-src 'self' https://cdn.example.com;
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
connect-src 'self' https://api.example.com;
font-src 'self' https://fonts.gstatic.com;
form-action 'self';
frame-ancestors 'none';
base-uri 'self';
upgrade-insecure-requests;
report-uri /csp-report;
report-to csp-endpoint;
2. Scripts inline baseados em nonce
Content-Security-Policy: script-src 'nonce-r@nd0mNonceHere' 'strict-dynamic';
<script nonce="r@nd0mNonceHere">
// this script executes; anything without the matching nonce does not
</script>
3. Scripts inline baseados em hash
Content-Security-Policy: script-src 'sha256-B2yPHKaXnvFWtRChIbabYmUBFZdVfKKXHbWtWidDVF8=';
Gere o hash com: echo -n "your inline script contents" | openssl dgst -sha256 -binary | openssl base64
4. Modo Report-Only (sem bloqueio, apenas monitorização)
Content-Security-Policy-Report-Only:
default-src 'self';
script-src 'self' https://cdn.example.com;
report-to csp-endpoint;
5. Endpoint Report-To (relatórios modernos)
Report-To: {"group":"csp-endpoint","max_age":10886400,"endpoints":[{"url":"https://example.com/csp-report"}]}
Content-Security-Policy: default-src 'self'; report-to csp-endpoint;
6. Exemplo de payload de violação
{
"csp-report": {
"document-uri": "https://example.com/checkout",
"referrer": "",
"violated-directive": "script-src 'self'",
"effective-directive": "script-src",
"original-policy": "default-src 'self'; report-uri /csp-report",
"disposition": "enforce",
"blocked-uri": "https://malicious.example/skimmer.js",
"line-number": 42,
"source-file": "https://example.com/checkout",
"status-code": 200,
"script-sample": ""
}
}
7. Middleware Express.js
app.use((req, res, next) => {
res.setHeader(
"Content-Security-Policy",
"default-src 'self'; script-src 'self' https://cdn.example.com; report-uri /csp-report",
);
next();
});
app.post("/csp-report", express.json({ type: "application/csp-report" }), (req, res) => {
console.log("CSP violation", req.body);
res.sendStatus(204);
});
8. Cloudflare Worker
export default {
async fetch(request, env) {
const response = await fetch(request);
const headers = new Headers(response.headers);
headers.set(
"Content-Security-Policy",
"default-src 'self'; script-src 'self' https://cdn.example.com; report-to csp-endpoint",
);
return new Response(response.body, { status: response.status, headers });
},
};
Referência alargada de diretivas
Para além das sete diretivas acima, o CSP define várias outras que surgem em trabalhos de reforço de segurança em produção:
| Diretiva | Finalidade |
|---|---|
strict-dynamic | Confia em scripts carregados por um script já considerado fiável (nonce ou hash). Simplifica o carregamento a partir de CDN. |
upgrade-insecure-requests | Atualiza automaticamente subrecursos http: para https:. Elimina avisos de conteúdo misto. |
require-trusted-types-for | Aplica Trusted Types em sinks do DOM perigosos (por exemplo, innerHTML, Function()). |
sandbox | Aplica isolamento no estilo iframe a toda a página. É poderoso e exige testes cuidadosos. |
form-action | Restringe para onde os envios de <form> podem fazer POST. Bloqueia redirecionamentos de phishing. |
base-uri | Fixa o elemento <base> a origens específicas. Previne ataques de injeção via <base>. |
manifest-src | Controla de onde pode ser carregado o manifesto de uma web-app. |
media-src | Restringe as fontes de <audio> e <video>. |
object-src | Restringe <object>, <embed>, <applet>. Defina como 'none' em sites modernos. |
worker-src | Restringe as fontes de Web Workers e Service Workers. |
Tenha cuidado com 'unsafe-inline' e 'unsafe-eval'. Ambas continuam a ser suportadas, mas desativam a maior parte da proteção do CSP contra XSS. 'strict-dynamic' com nonces é o caminho de substituição moderno.
Veja isto no seu próprio site
O CSP é uma camada de defesa do lado do cliente, e uma camada crítica para a conformidade com o PCI DSS 4.0.1. Mas o CSP, por si só, não impediu o ataque ao Polyfill.io em 2024, porque o domínio comprometido estava na lista de permitidos. O cside adiciona inventário de scripts e análise de payloads sobre o CSP para fechar essa lacuna. Plano gratuito disponível.
Como é que o CSP previne ataques baseados no navegador?
Mitigação de ataques XSS
Num ataque de cross-site scripting, ou ataque XSS, um atacante geralmente encontra uma forma de injetar e executar código JavaScript malicioso na sua página (por exemplo, através de um input não sanitizado). Por defeito, um CSP bloqueia a execução de qualquer script inline na página, a menos que uma diretiva da política o permita explicitamente. Isto significa que, se um atacante injetar algo como <script>evilCode()</script> numa página, este não será executado (a menos que ‘unsafe-inline’ esteja permitido no CSP!)
Bloqueio de scripts de terceiros não autorizados
Muitos sites têm scripts de terceiros para coisas como análise, monitorização de utilizadores e publicidade. Com um CSP, os proprietários dos sites podem limitar quais os sites externos que podem efetivamente fornecer scripts. Por exemplo, se pretender servir conteúdo apenas a partir de analytics._example_.com e não de mais nada em example.com, a diretiva script-src do CSP do seu site pode permitir explicitamente apenas isso.
Prevenção de exfiltração de dados
Como referido anteriormente, um CSP pode restringir ações numa página que possam ser usadas para impedir que código JavaScript malicioso envie dados de volta para um domínio controlado por um atacante. Usar a diretiva connect-src bloqueia pedidos de rede para servidores não autorizados, e pode ser combinada com a diretiva form-action para garantir que os dados só são enviados para o seu domínio.
Aplicação de práticas de navegação seguras
Um CSP tem diretivas para impor comportamentos seguros que melhoram a segurança geral do seu site.
- Um exemplo disto é
upgrade-insecure-requests, que obriga o navegador a carregar todos os recursos via HTTPS, evitando problemas de conteúdo misto e inseguro. - Outra diretiva é
frame-ancestors, que pode prevenir ataques de clickjacking ao impedir que a sua página seja incorporada numa frame controlada por um atacante.
Em conjunto, estas políticas resultam numa base sólida de segurança do lado do cliente para aplicações web modernas.
Limitações de segurança do CSP
Usar uma Content Security Policy oferece uma proteção forte, mas não é uma solução definitiva para o seu site, como destacado no nosso artigo “Why Content Security Policy Doesn’t Work”.
As políticas podem desalinhar-se ao longo do tempo, e as listas de permitidos não inspecionam o comportamento do código. Cada navegador principal implementa o CSP à sua própria maneira, com pequenas diferenças. Chrome, Firefox, Safari e Edge suportam todos o CSP Level 3; o comportamento dos relatórios e os formatos de violação podem variar. Para validar e manter a sua política, teste-a regularmente com as ferramentas de programador do navegador e scanners automatizados como o Mozilla Observatory ou o SecurityHeaders.io.
Combinar um CSP com um camada ativa de segurança do lado do cliente como o cside, para adicionar inspeção e bloqueio em tempo real aos scripts de terceiros no seu site, proporciona-lhe uma excelente camada de defesa, com tranquilidade para os seus clientes. Do ponto de vista de governação, documentar as atualizações do CSP e monitorizar os relatórios de violação melhora a auditabilidade e a conformidade a longo prazo com frameworks como a ISO 27001 e a OWASP ASVS.
O CSP funciona para a conformidade com o PCI DSS 6.4.3?
Ao abrigo do Requisito 6.4.3 do PCI DSS 4.0.1, os comerciantes têm de provar que cada script do lado do cliente está autorizado e provar a integridade do script. O CSP e o SRI ajudam a percorrer parte desse caminho. O CSP limita quais os domínios que podem carregar scripts, e o SRI verifica que o código de um ficheiro não foi alterado. Mas, em conjunto, são uma solução estática para um problema dinâmico. Os scripts dinâmicos atualizam-se e os hashes deixam de corresponder. A manutenção manual de listas CSP é quase impossível.
A maioria dos sites modernos usa scripts de terceiros dinâmicos, pelo que estes controlos se degradam rapidamente. Esta abordagem tipicamente fica aquém das provas exigidas para o PCI 6.4.3.
Um exemplo de Content Security Policy (CSP): quando um CSP estrito quebrou a produção
O dia em que o checkout deixou de funcionar: como um CSP estrito quebrou a produção
Tudo começou com um deployment novo e vulgar. Nada de especial, apenas uma nova Content Security Policy para tornar uma loja de ecommerce mais segura e impedir que atacantes introduzissem código malicioso às escondidas.
O default-src ‘none’ limpo foi definido sem testes. E assim, no momento em que o CSP foi ativado, o site bloqueou serviços de que efetivamente precisava. A análise (analytics) deixou de funcionar e, pior ainda, o sistema de pagamentos foi bloqueado. Os clientes não conseguiam concluir as suas encomendas e o sistema de checkout avariou. Os programadores puseram mãos à obra e mudaram o cabeçalho para Content-Security-Policy-Report-Only, recolhendo os registos de violação. A partir daí, construíram uma lista de permitidos (script-src ‘self’ https://pay.examplecase.com) com todos os serviços de que a loja online precisava para funcionar corretamente.
Depois de afinar o CSP, a equipa fez o deployment sem qualquer avaria. Este tipo de descuido é um erro comum quando as equipas gerem o CSP internamente. Esquecer-se de adicionar um novo script de marketing à lista de permitidos, erros técnicos de configuração, ou problemas com scripts dinâmicos que quebram os protocolos de hashing tornam o CSP um pesadelo de gerir em grande escala.
Gere e mantenha o seu CSP automaticamente com a cside
Escrever e manter uma Content Security Policy à mão é onde a maioria das equipas fica presa: cada nova tag de marketing, script de terceiros dinâmico ou alteração de endpoint de um fornecedor pode quebrar a política ou alargar silenciosamente a lista de permitidos. A cside elimina esse trabalho manual.
A cside observa os scripts que o seu site realmente carrega e gera por si um cabeçalho CSP pronto a implementar a partir de sessões reais do navegador, mantendo-o atualizado à medida que esses scripts mudam, para que não tenha de perseguir manualmente as atualizações da lista de permitidos. Obtém uma Content Security Policy que reflete o que o seu site realmente executa, além do inventário de scripts e da deteção de adulteração que o CSP por si só não consegue oferecer para os requisitos §6.4.3 e §11.6.1 da PCI DSS 4.0.1.
Não há nada para programar. Registe-se no plano gratuito, adicione o seu domínio e a cside começa a gerar o seu CSP a partir do tráfego real. Explore a solução de gestão de CSP ou veja como a cside colma as lacunas que um CSP deixa em aberto.