Garantir que a CSP seja eficaz contra ataques XSS

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. Os CSPs mitigam os ataques de scripting em vários locais (XSS) porque podem bloquear scripts não seguros injetados por invasores. No entanto, o CSP pode ser facilmente ignorado se não for restrito o suficiente. Confira Mitigar scripting em vários sites (XSS) com uma Política de Segurança de Conteúdo (CSP) rigorosa para mais informações. O Lighthouse coleta as CSPs aplicadas no documento principal e informa os problemas do CSP Evaluator, se eles puderem ser ignorados.

O relatório do Lighthouse informa que nenhuma CSP foi encontrada no modo de aplicação.
Relatório do Lighthouse avisando que nenhuma CSP foi encontrada no modo de restrição.

Práticas necessárias para um CSP não ignorado

Implemente as práticas a seguir para garantir que sua CSP não possa ser ignorada. Se for possível ignorar a CSP, o Lighthouse vai emitir um aviso de alta gravidade.

A CSP tem como alvo XSS

Para segmentar XSS, uma CSP precisa incluir as diretivas script-src, object-src e base-uri. A 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, default-src pode ser usado para configurar uma política ampla em vez de muitas diretivas, incluindo script-src e object-src.

O 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.

A CSP usa valores de uso único ou hashes para evitar violações da lista de permissões

Um CSP que configura uma lista de permissões para script-src depende do pressuposto 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 benignos comuns, como a exposição de interfaces JSONP e a hospedagem de cópias da biblioteca AngularJS, permitem que os invasores escapem dos limites do CSP.

Na prática, embora isso não seja óbvio para os autores de aplicativos, a maioria das listas de permissões do script-src pode ser burlada por um invasor com um bug XSS e fornece pouca proteção contra injeção de script. Por outro lado, as abordagens com base em valor de uso único e em hash não enfrentam esses problemas e facilitam a adoção e 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 por invasores:

CSP:

script-src https://trusted.example.com

HTML:

<script src="https://trusted.example.com/path/jsonp?callback=alert(document.domain)//"></script>

Para evitar esse problema, um CSP precisa permitir scripts individualmente usando valores de uso único ou hashes e usar "strict-dynamic". em vez de uma lista de permissões.

Mais recomendações para um CSP seguro

Implemente as práticas a seguir para aumentar a segurança e a compatibilidade. Se a CSP não seguir uma das recomendações, o Lighthouse vai emitir um aviso de gravidade média.

Configurar a geração de relatórios da CSP

Configurar um destino de relatório ajuda a monitorar falhas. É possível definir o destino do relatório usando as diretivas report-uri ou report-to. No momento, o report-to não é compatível com todos os navegadores mais recentes. Por isso, recomendamos usar ambos ou apenas report-uri.

Se algum conteúdo violar a CSP, o navegador vai enviar uma denúncia ao destino configurado. Verifique se você tem um aplicativo configurado no destino que processa esses relatórios.

Definir a CSP em um cabeçalho HTTP

Uma CSP pode ser definida em uma metatag como esta:

<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 metatag ignorará a CSP. Além disso, frame-ancestors, sandbox e relatórios não são compatíveis com as CSPs de metatag.

Garantir que o CSP seja compatível com versões anteriores

Nem todos os navegadores oferecem suporte a valores de uso único/hashes da CSP. Portanto, é recomendável adicionar unsafe-inline como substituto para navegadores que não estão em conformidade. Se o navegador for compatível com 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 substituta para qualquer navegador que não esteja em conformidade. A lista de permissões será ignorada em navegadores compatíveis com strict-dynamic.

Como desenvolver uma CSP rigorosa

Confira abaixo um exemplo de como usar uma CSP rigorosa com uma política baseada no 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 no lado do servidor sempre que a página fosse carregada. unsafe-inline e https: são ignorados em navegadores modernos devido ao valor de uso único e strict-dynamic. Para mais informações sobre como adotar uma CSP rigorosa, acesse o Guia de CSP rigorosa.

É possível verificar possíveis desvios em um CSP usando o Lighthouse e o CSP Evaluator. Se você quiser testar uma nova CSP sem o risco de corromper as páginas atuais, defina a CSP no modo somente relatório usando Content-Security-Policy-Report-Only como o nome do cabeçalho. Isso vai enviar violações da CSP para todos os destinos de relatórios configurados com report-to e report-uri, mas não vai aplicar a CSP.