Gerador de Content Security Policy
Gera cabeçalhos Content-Security-Policy.
Build a Content-Security-Policy. Common keywords: 'self' 'none' 'unsafe-inline' 'unsafe-eval' 'strict-dynamic' data: https: blob:
Visão geral
Uma Content-Security-Policy informa ao navegador de quais origens ele pode carregar recursos. Seu valor prático é mais restrito do que o nome sugere: o CSP não corrige cross-site scripting, ele o contém. Se uma injeção escapar da sua codificação de saída, é uma política rigorosa que impede o script injetado de executar ou de mandar o que roubou para o servidor de um atacante.
O cabeçalho é uma lista de diretivas separadas por ponto e vírgula, cada uma nomeando um tipo de recurso e as origens permitidas para ele. Esta ferramenta dá a você um campo por diretiva, preenche uma política inicial sensata e mostra o cabeçalho montado conforme você digita.
Como usar
- Comece pela política já preenchida —
default-src 'self',object-src 'none',base-uri 'self',frame-ancestors 'none'. Esse é um piso razoável para um site que serve os próprios ativos. - Adicione as origens de que você realmente precisa, uma diretiva por vez. Separe múltiplas origens com espaços.
- Deixe uma diretiva em branco para omiti-la; diretivas em branco caem no
fallback do
default-src. - Copie o cabeçalho e faça o deploy primeiro como
Content-Security-Policy-Report-Only. Leia os relatórios de violação, ajuste a política e só então mude para o nome de cabeçalho que aplica de fato.
As palavras-chave de origem
| Palavra-chave | Significado |
|---|---|
'self' | A própria origem do documento — mesmo esquema, host e porta |
'none' | Absolutamente nada. Só tem sentido como origem única |
'unsafe-inline' | Permite <script> / <style> inline e handlers de evento inline |
'unsafe-eval' | Permite eval, new Function e argumentos em string para setTimeout |
'strict-dynamic' | Confia em scripts criados por um script já confiável. Faz com que as listas de hosts daquela diretiva sejam ignoradas |
data: | Permite URIs data:. Razoável em img-src, perigoso em script-src |
https: | Qualquer origem por HTTPS. Amplo — normalmente um sinal de que a política precisa ser estreitada |
blob: | Permite URLs blob:, necessárias para Web Workers criados a partir de código gerado |
Hashes ('sha256-…') e nonces ('nonce-…') são as alternativas rigorosas ao
'unsafe-inline'. Um hash cobre um script inline específico cujo conteúdo nunca
muda, o que combina com sites gerados estaticamente. Um nonce é um valor
aleatório novo em cada resposta, o que combina com páginas renderizadas no
servidor. Você não pode usar nonce em uma hospedagem de arquivos estáticos,
porque não existe uma etapa por requisição para gerá-lo.
As diretivas fáceis de errar
base-uri não é coberta por default-src. Sem ela, uma tag <base href>
injetada pode redirecionar todas as URLs relativas da página para o host de um
atacante — inclusive as suas tags de script — sem nunca injetar um script.
Defina-a como 'self' ou 'none'.
form-action também não é coberta por default-src. Sem ela, um formulário
injetado pode enviar o que os seus usuários digitaram para outra origem.
frame-ancestors substitui o X-Frame-Options. Quando os dois discordam,
navegadores modernos seguem o CSP, então definir apenas o cabeçalho antigo deixa
os navegadores mais novos sem restrição alguma daquilo que você pretendia dizer.
object-src 'none' merece ser definida explicitamente. Conteúdo de plugin é
um caminho de execução legado, sem uso legítimo em um site novo.
connect-src é a que as pessoas esquecem. Ela governa fetch, XHR,
WebSockets e sendBeacon — exatamente por onde um script injetado exfiltraria
dados. Um script-src apertado com um connect-src escancarado deixa aberta a
porta que ele deveria fechar.
Exemplos
Um site estático que serve os próprios ativos, sem scripts de terceiros:
default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none';
form-action 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:;
font-src 'self'; connect-src 'self'; upgrade-insecure-requests
O mesmo site com uma tag de analytics, permitindo somente as origens específicas
de que ela precisa em vez de https::
script-src 'self' https://www.googletagmanager.com;
connect-src 'self' https://www.google-analytics.com
Coletando relatórios de violação
O modo Report-Only só é útil se você ler os relatórios. Existem dois mecanismos e o suporte dos navegadores está dividido entre eles, então um rollout normalmente envia os dois.
report-uri /csp-report é a diretiva mais antiga. Está obsoleta, mas ainda é a
de suporte mais amplo, e envia um corpo JSON descrevendo o recurso bloqueado, a
diretiva que o bloqueou e a URL do documento.
report-to é a substituta. Ela nomeia um grupo de relatório configurado por um
cabeçalho de resposta Reporting-Endpoints separado, o que permite a um mesmo
endpoint atender relatórios de CSP, de depreciação e de intervenção juntos.
Qualquer que seja a escolha, espere ruído. Extensões de navegador injetam
scripts e estilos nas páginas, e as violações delas ficam idênticas às suas no
relatório. O sinal é uma violação que aparece para muitos usuários distintos na
mesma URL de documento e na mesma diretiva; um blocked-uri isolado apontando
para o esquema chrome-extension: é o gerenciador de senhas de alguém.
Nenhuma das duas diretivas funciona em uma tag meta. Relatórios exigem o
cabeçalho HTTP de verdade.
Observações
upgrade-insecure-requests reescreve requisições de sub-recursos em http://
para https:// antes de elas serem feitas. É um auxílio de migração para
páginas com conteúdo misto, não um substituto para corrigir as URLs, e não se
aplica à navegação para outros sites.
style-src normalmente é o último 'unsafe-inline' a cair, e muitas vezes o que
vale a pena manter. Atributos style inline não podem ser cobertos por hash —
seria preciso 'unsafe-hashes' mais um hash para cada valor de atributo
distinto — e injeção de CSS é um problema bem mais estreito do que injeção de
script. Gastar o esforço primeiro no script-src é a troca melhor.
Faça o deploy com Content-Security-Policy-Report-Only antes de aplicar de
verdade. Uma política uma diretiva rigorosa demais não degrada com elegância:
ela quebra a página silenciosamente para todo visitante cujo navegador a aplique,
e você vai descobrir pelos usuários, não pelos seus próprios testes.
Se quiser verificar o que um site em produção envia hoje, o verificador de cabeçalhos HTTP mostra os cabeçalhos de resposta de qualquer URL.