Como usar o nonce gerado
A predefinição Nonce de CSP está ativa: 16 bytes aleatórios em Base64, o que dá um valor de 24 caracteres terminado em
==.Pronto para colar mostra o header e a tag correspondente, por exemplo:
Content-Security-Policy: script-src 'nonce-SQu4/GjzG3plY6CUwsx8gA==' <script nonce="SQu4/GjzG3plY6CUwsx8gA==" src="/app.js"></script>Use-o para testar uma política em uma página de teste local ou em uma configuração de staging. Clique em Gerar novo para outro valor.
Um nonce copiado desta página é o mesmo em todas as requisições, então não protege nada em produção. Implantações reais o geram no código do servidor, como mostrado abaixo.
Como funciona uma política baseada em nonce
Com script-src 'nonce-…', o navegador só executa um script se o atributo nonce dele bater com o valor no header daquela mesma resposta. As suas próprias tags <script> recebem o atributo dos seus templates. Marcação que um atacante injeta por uma falha de XSS não conhece o valor, porque ele muda a cada carregamento de página, e o navegador se recusa a executá-la.
Três detalhes importam na prática:
- O valor é comparado como texto. Copie exatamente, com o
=, e mantenha as aspas simples em volta de'nonce-…'no header, mas não no atributo. - Os navegadores escondem o atributo. Depois que a página carrega,
getAttribute("nonce")devolve uma string vazia e seletores CSS não enxergam o valor, o que impede alguns truques de exfiltração. Scripts que precisam dele leem a propriedadenonce. 'strict-dynamic'permite que um script confiável, com nonce, carregue outros scripts sem que cada um precise do próprio nonce. É o parceiro habitual dos nonces em uma política moderna, e com ele o navegador ignora allowlists de hosts comohttps:.
A política também pode ser entregue em uma tag <meta http-equiv="Content-Security-Policy">; nonces funcionam ali também, embora algumas diretivas, como frame-ancestors, não funcionem.
Como gerar um nonce por resposta
O servidor cria 16 bytes aleatórios para cada requisição, coloca-os no header e passa o mesmo valor para o template. Em Node.js, sem nenhum framework:
const crypto = require("crypto");
const http = require("http");
http.createServer((req, res) => {
const nonce = crypto.randomBytes(16).toString("base64");
res.setHeader("Content-Security-Policy",
`script-src 'nonce-${nonce}' 'strict-dynamic'; object-src 'none'; base-uri 'none'`);
res.setHeader("Content-Type", "text/html; charset=utf-8");
res.end(`<script nonce="${nonce}" src="/app.js"></script>`);
}).listen(8080);
Em Python, base64.b64encode(secrets.token_bytes(16)).decode() gera o mesmo tipo de valor; frameworks com middleware de CSP costumam expô-lo como variável de template. Seja qual for a sua escolha, garanta que um cache na frente do servidor não guarde o HTML com um nonce e o entregue a todos os visitantes. Fazer cache do corpo da página enquanto o header muda quebra todos os scripts; fazer cache dos dois repete o nonce para todo mundo.
Nonces, hashes e SRI
Um nonce aprova uma tag de script para uma resposta. Um hash CSP aprova um script inline específico para sempre: 'sha256-…' é o SHA-256 em Base64 do texto exato entre <script> e </script>. Para <script>alert('Hello');</script>, ele é:
script-src 'sha256-gKHd+pSZOJ3MwBsFalomyNobAcinjJ44ArqbIKlcniQ='
Hashes servem para sites estáticos e trechos inline que nunca mudam; calcule-os com a ferramenta SHA-256 para Base64, atento aos espaços em branco, já que um espaço a mais muda o hash. O Subresource Integrity é um terceiro mecanismo com os mesmos digests em Base64: integrity="sha384-…" em um <script src> faz o navegador conferir o próprio arquivo baixado. O gerador de hash SRI monta essas tags.
Perguntas frequentes
Qual deve ser o tamanho de um nonce CSP?
A especificação de CSP pede pelo menos 128 bits de aleatoriedade antes da codificação, ou seja, 16 bytes ou 24 caracteres Base64. Mais longo não tem problema; mais curto enfraquece a proteção.
Posso reutilizar o mesmo nonce em todas as páginas?
Não. Um nonce fixo fica visível no seu HTML, então um atacante que consiga injetar marcação pode copiá-lo para a própria tag <script>. Gere um novo para cada resposta HTTP.
Um site estático pode usar nonces CSP?
Só se algo na frente dele reescrever cada resposta, como uma edge function que insere um nonce novo. Uma hospedagem puramente estática serve os mesmos bytes para todo mundo, então use hashes de script ('sha256-…') ou arquivos externos de 'self'.
Caracteres URL-safe são permitidos em um nonce?
São. A gramática da CSP aceita os dois alfabetos Base64: letras, dígitos, +, /, - e _, com até dois = no final. O Base64 padrão é a escolha comum.