Uma política de segurança de conteúdo (CSP) ajuda a garantir que qualquer conteúdo carregado na página seja confiável para o proprietário do site. As CSPs mitigam ataques de scripting em vários locais (XSS) porque podem bloquear scripts inseguros injetados por invasores. No entanto, o CSP pode ser facilmente ignorado se não for rigoroso o suficiente. Para mais informações, consulte Mitigar o scripting em vários locais (XSS) com uma Política de Segurança de Conteúdo (CSP) rígida. O Lighthouse coleta CSPs aplicadas no documento principal e informa problemas do CSP Evaluator se eles puderem ser ignorados.
Práticas obrigatórias para um CSP não bypassável
Implemente as práticas a seguir para garantir que o CSP não possa ser ignorado. Se o CSP puder ser ignorado, o Lighthouse vai emitir um aviso de alta gravidade.
CSPs segmentam XSS
Para segmentar XSS, a CSP precisa incluir as diretivas script-src
, object-src
e base-uri
. O CSP também não pode ter erros de sintaxe.
script-src
e object-src
protegem uma página contra scripts e plug-ins não seguros, respectivamente. Como alternativa, o default-src
pode ser usado para configurar uma política ampla em vez de muitas diretivas, incluindo script-src
e object-src
.
base-uri
impede a injeção de tags <base>
não autorizadas, que podem ser usadas para redirecionar todos os URLs relativos (como scripts) para um domínio controlado por invasores.
O CSP usa valores de uso único ou hashes para evitar desvios de listas de permissões
Um CSP que configura uma lista de permissões para script-src
depende da suposição de que todas as respostas provenientes de um domínio confiável são seguras e podem ser executadas como scripts. No entanto, essa suposição não se aplica a aplicativos modernos. Alguns padrões comuns e benignos, como a exposição de interfaces JSONP e cópias de hospedagem da biblioteca AngularJS, permitem que os invasores escapem dos limites do CSP.
Na prática, embora possa não ser óbvio para os autores do aplicativo, a maioria das listas de permissões script-src
pode ser contornada por um invasor com um bug XSS e oferece pouca proteção contra a injeção de scripts. Por outro lado, as abordagens baseadas em valor de uso único e em hash não têm esses problemas e facilitam a adoção e a manutenção de uma política mais segura.
Por exemplo, este código usa um endpoint JSONP hospedado em um domínio confiável para injetar um script controlado pelo invasor:
CSP:
script-src https://trusted.example.com
HTML:
<script src="https://trusted.example.com/path/jsonp?callback=alert(document.domain)//"></script>
Para evitar que isso aconteça, uma CSP precisa permitir scripts individualmente usando valores de uso único ou hashes e usar "strict-dynamic" em vez de uma lista de permissões.
Outras recomendações para um CSP seguro
Implemente as práticas a seguir para aumentar a segurança e a compatibilidade. Se o CSP não seguir uma das recomendações, o Lighthouse vai emitir um aviso de gravidade média.
Configurar os relatórios do CSP
Configurar um destino de relatório ajuda a monitorar falhas. É possível definir o destino dos relatórios usando as diretivas report-uri
ou report-to
. No momento, report-to
não é compatível com todos os navegadores modernos. Por isso, recomendamos usar os dois ou apenas report-uri
.
Se algum conteúdo violar o CSP, o navegador vai enviar um relatório para o destino configurado. Verifique se você tem um aplicativo configurado nesse destino para processar esses relatórios.
Definir a CSP em um cabeçalho HTTP
Uma CSP pode ser definida em uma metatag assim:
<meta http-equiv="Content-Security-Policy" content="script-src 'none'">
No entanto, se possível, defina uma CSP em um cabeçalho de resposta HTTP. Uma injeção antes da meta tag vai contornar o CSP. Além disso, frame-ancestors
, sandbox
e relatórios não são compatíveis com CSPs de metatag.
Conferir se a CSP é compatível com versões anteriores
Nem todos os navegadores oferecem suporte a valores de uso único/hashes de CSP. Portanto, é recomendável adicionar unsafe-inline
como uma alternativa para navegadores não compatíveis. Se o navegador oferecer suporte a valores de uso único/hashes, unsafe-inline
será ignorado.
Da mesma forma, strict-dynamic
não é compatível com todos os navegadores. É recomendável definir uma lista de permissões como substituto para todos os navegadores não compatíveis. A lista de permissões será ignorada em navegadores compatíveis com strict-dynamic
.
Como desenvolver um CSP estrito
Confira abaixo um exemplo de uso de um CSP rígido com uma política baseada em valor de uso único.
CSP:
script-src 'nonce-random123' 'strict-dynamic' 'unsafe-inline' https:;
object-src 'none';
base-uri 'none';
report-uri https://reporting.example.com;
HTML:
<script nonce="random123" src="https://trusted.example.com/trusted_script.js"></script>
random123
seria qualquer string base64 gerada do lado do servidor sempre que a página é carregada. unsafe-inline
e https:
são ignorados em navegadores modernos devido ao valor de uso único e ao strict-dynamic
. Para mais informações sobre a adoção de um CSP rígido, consulte o guia de CSP rígido.
É possível verificar um CSP em busca de possíveis desvios usando o Lighthouse e o CSP Evaluator. Se você quiser testar um novo CSP sem o risco de quebrar as páginas atuais, defina o CSP no modo somente relatório usando Content-Security-Policy-Report-Only
como o nome do cabeçalho. Isso vai enviar violações do CSP para todos os destinos de relatório que você configurou com report-to
e report-uri
, mas não vai aplicar o CSP.