Garantir que a CSP seja eficaz contra ataques XSS

Uma Política de Segurança de Conteúdo (CSP) ajuda a garantir que o proprietário do site confie na confiança de qualquer conteúdo carregado na página. Os CSPs mitigam ataques de scripting em vários locais (XSS) porque podem bloquear scripts não seguros injetados por invasores. No entanto, a CSP poderá ser facilmente ignorada se não for rigorosa o suficiente. Saiba mais em Mitigar scripting em vários sites (XSS) com uma Política de Segurança de Conteúdo (CSP) rigorosa. O Lighthouse coleta as CSPs aplicadas no documento principal e informa problemas do CSP Evaluator se eles puderem ser ignorados.

Relatório do Lighthouse informando que nenhuma CSP foi encontrada no modo de aplicação.
Alerta do Lighthouse informando que nenhuma CSP foi encontrada no modo de aplicação.

Práticas necessárias para uma CSP não ignorável

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

A CSP é direcionada a XSS

Para segmentar XSS, uma CSP precisa incluir as diretivas script-src, object-src e base-uri. A CSP também não deve ter erros de sintaxe.

O script-src e o 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 que a lista de permissões seja ignorada

Uma CSP que configura uma lista de permissões para script-src depende do pressuposto de que todas as respostas 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 da CSP.

Na prática, embora isso não seja óbvio para os autores de aplicativos, a maioria das listas de permissões de 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 baseadas em valor de uso único e em hash não apresentam 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 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 ser ignorado, uma CSP precisa permitir scripts individualmente com valores de uso único ou hashes e usar "strict-dynamic" em vez de uma lista de permissões.

Mais recomendações para uma CSP segura

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 emitirá um aviso de gravidade média.

Configurar relatórios de 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, o report-to não é compatível com todos os navegadores modernos. Portanto, é recomendável 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 nesse 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, defina uma CSP em um cabeçalho de resposta HTTP, se possível. Uma injeção antes da metatag ignora a CSP. Além disso, frame-ancestors, sandbox e relatórios não são compatíveis com as CSPs de metatags.

Verifique se a CSP é compatível com versões anteriores

Nem todos os navegadores são compatíveis com valores de uso único/hashes da CSP. Portanto, é recomendável adicionar unsafe-inline como substituto para navegadores que não estejam em conformidade. Se o navegador tiver 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 substituta para todos os navegadores que não estiverem em conformidade. Essa lista será ignorada em navegadores com suporte para strict-dynamic.

Como desenvolver uma CSP rigorosa

Confira abaixo um exemplo de uso de uma CSP rigorosa 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 no lado do servidor toda vez que a página fosse 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 uma CSP rigorosa, confira o guia de CSPs rigorosas.

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