A Content-Security-Policy
metatag permite reduzir o risco de ataques XSS , permitindo definir de onde os recursos podem ser carregados, impedindo que os navegadores carreguem dados de qualquer outro local. Isso torna mais difícil para um invasor injetar código malicioso no seu site.
Bati minha cabeça contra uma parede de tijolos tentando descobrir por que estava recebendo erros de CSP, um após o outro, e não parecia haver nenhuma instrução clara e concisa sobre como isso funciona. Então, aqui está minha tentativa de explicar brevemente alguns pontos do CSP, concentrando-me principalmente nas coisas que achei difíceis de resolver.
Por uma questão de brevidade, não escreverei a tag completa em cada amostra. Em vez disso, mostrarei apenas a content
propriedade, portanto, uma amostra que diz content="default-src 'self'"
significa isso:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">
1. Como permitir várias fontes?
Você pode simplesmente listar suas fontes após uma diretiva como uma lista separada por espaço:
content="default-src 'self' https://example.com/js/"
Observe que não há aspas em torno de outros parâmetros além dos especiais , como 'self'
. Além disso, não há dois pontos ( :
) após a diretiva. Apenas a diretiva e, em seguida, uma lista de parâmetros separados por espaço.
Tudo abaixo dos parâmetros especificados é implicitamente permitido. Isso significa que no exemplo acima, essas fontes seriam válidas:
https://example.com/js/file.js
https://example.com/js/subdir/anotherfile.js
Estes, no entanto, não seriam válidos:
http://example.com/js/file.js
^^^^ wrong protocol
https://example.com/file.js
^^ above the specified path
2. Como usar diretivas diferentes, o que cada uma delas faz?
As diretivas mais comuns são:
default-src
a política padrão para carregar javascript, imagens, CSS, fontes, solicitações AJAX, etc.
script-src
define fontes válidas para arquivos javascript
style-src
define fontes válidas para arquivos css
img-src
define fontes válidas para imagens
connect-src
define destinos válidos para XMLHttpRequest (AJAX), WebSockets ou EventSource. Se for feita uma tentativa de conexão com um host que não é permitido aqui, o navegador emulará um 400
erro
Existem outros, mas esses são os de que você provavelmente precisará.
3. Como usar várias diretivas?
Você define todas as suas diretivas dentro de uma metatag encerrando-as com ponto-e-vírgula ( ;
):
content="default-src 'self' https://example.com/js/; style-src 'self'"
4. Como lidar com portas?
Tudo, exceto as portas padrão, precisa ser permitido explicitamente, adicionando o número da porta ou um asterisco após o domínio permitido:
content="default-src 'self' https://ajax.googleapis.com http://example.com:123/free/stuff/"
O acima resultaria em:
https://ajax.googleapis.com:123
^^^^ Not ok, wrong port
https://ajax.googleapis.com - OK
http://example.com/free/stuff/file.js
^^ Not ok, only the port 123 is allowed
http://example.com:123/free/stuff/file.js - OK
Como mencionei, você também pode usar um asterisco para permitir explicitamente todas as portas:
content="default-src example.com:*"
5. Como lidar com diferentes protocolos?
Por padrão, apenas protocolos padrão são permitidos. Por exemplo, para permitir WebSockets, ws://
você terá que permitir explicitamente:
content="default-src 'self'; connect-src ws:; style-src 'self'"
^^^ web sockets are now allowed on all domains and ports
6. Como permitir o protocolo de arquivo file://
?
Se você tentar defini-lo como tal, não funcionará. Em vez disso, você o permitirá com o filesystem
parâmetro:
content="default-src filesystem"
7. Como usar scripts embutidos e definições de estilo?
A menos que seja explicitamente permitido, você não pode usar definições de estilo embutido, codificar dentro de <script>
tags ou em propriedades de tags como onclick
. Você os permite assim:
content="script-src 'unsafe-inline'; style-src 'unsafe-inline'"
Você também precisará permitir explicitamente imagens codificadas em linha de base64:
content="img-src data:"
8. Como permitir eval()
?
Tenho certeza de que muitas pessoas diriam que não, pois 'eval é mau' e a causa mais provável para o fim iminente do mundo. Essas pessoas estariam erradas. Certamente, você pode definitivamente fazer grandes furos na segurança do seu site com avaliação, mas possui casos de uso perfeitamente válidos. Você só precisa ser esperto ao usá-lo. Você permite assim:
content="script-src 'unsafe-eval'"
9. O que exatamente 'self'
significa?
Você pode 'self'
significar host local, sistema de arquivos local ou qualquer coisa no mesmo host. Isso não significa nada disso. Significa fontes que possuem o mesmo esquema (protocolo), mesmo host e mesma porta que o arquivo em que a política de conteúdo está definida. Servindo seu site por HTTP? Não há https para você, a menos que você o defina explicitamente.
Eu usei 'self'
na maioria dos exemplos, pois geralmente faz sentido incluí-lo, mas não é de forma alguma obrigatório. Deixe de fora se não precisar.
Mas espere um minuto! Não posso simplesmente usar content="default-src *"
e acabar com isso?
Não. Além das óbvias vulnerabilidades de segurança, isso também não funcionará como você esperaria. Embora alguns documentos afirmem que isso permite algo, isso não é verdade. Ele não permite inline ou avaliações; portanto, para realmente tornar seu site ainda mais vulnerável, você usaria o seguinte:
content="default-src * 'unsafe-inline' 'unsafe-eval'"
... mas eu confio que você não vai.
Leitura adicional:
http://content-security-policy.com
http://en.wikipedia.org/wiki/Content_Security_Policy