Asegúrate de que la CSP sea eficaz contra los ataques XSS

Una Política de Seguridad del Contenido (CSP) ayuda a garantizar que cualquier contenido que se cargue en una página sea de confianza para el propietario del sitio. Los CSPs mitigan los ataques de secuencias de comandos entre sitios (XSS) porque pueden bloquear secuencias de comandos no seguras insertadas por atacantes. Sin embargo, el CSP se puede evadir con facilidad si no es lo suficientemente estricto. Consulta Mitiga la secuencia de comandos entre sitios (XSS) con una política de seguridad del contenido (CSP) estricta para obtener más información. Lighthouse recopila los CSPs aplicados en el documento principal y, luego, informa los problemas desde el CSP Evaluator si se pueden omitir.

El informe de Lighthouse advierte que no se encontró ninguna CSP en el modo de aplicación.
Informe de Lighthouse que advierte que no se encuentra ninguna CSP en el modo de aplicación.

Prácticas requeridas para un CSP que no se puede omitir

Implementa las siguientes prácticas para garantizar que no se pueda omitir tu CSP. Si se puede omitir el CSP, Lighthouse emitirá una advertencia de gravedad alta.

La CSP apunta a XSS

Para apuntar a XSS, un CSP debe incluir las directivas script-src, object-src y base-uri. La CSP tampoco debe tener errores de sintaxis.

script-src y object-src protegen una página de secuencias de comandos no seguras y complementos no seguros, respectivamente. Como alternativa, se puede usar default-src para configurar una política amplia en lugar de muchas directivas, incluidas script-src y object-src.

base-uri evita la inserción de etiquetas <base> no autorizadas que pueden usarse para redireccionar todas las URLs relativas (como secuencias de comandos) a un dominio controlado por el atacante.

La CSP usa nonces o hashes para evitar omisiones de listas de entidades permitidas

Un CSP que configura una lista de entidades permitidas para script-src se basa en la suposición de que todas las respuestas provenientes de un dominio de confianza son seguras y se pueden ejecutar como secuencias de comandos. Sin embargo, esta suposición no se aplica a las aplicaciones modernas. algunos patrones comunes y benignos, como exponer interfaces JSONP y alojar copias de la biblioteca AngularJS, permiten a los atacantes escapar de los límites de la CSP.

En la práctica, si bien puede no ser obvio para los autores de las aplicaciones, un atacante puede eludir la mayoría de las listas de entidades permitidas de script-src con un error de XSS y proporcionar poca protección contra la inyección de secuencias de comandos. En cambio, los enfoques basados en nonce y hash no se ven afectados por estos problemas y facilitan la adopción y el mantenimiento de una política más segura.

Por ejemplo, este código usa un extremo JSONP alojado en un dominio de confianza para insertar una secuencia de comandos controlada por el atacante:

CSP:

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

HTML:

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

Para evitar que se omita, un CSP debe permitir secuencias de comandos que usen nonces o hashes de forma individual y usar "strict-dynamic" en lugar de una lista de entidades permitidas.

Recomendaciones adicionales para una CSP segura

Implementa las siguientes prácticas para aumentar la seguridad y compatibilidad. Si el CSP no sigue una de las recomendaciones, Lighthouse emitirá una advertencia de gravedad media.

Configura los informes de CSP

Configurar un destino de informe ayudará a supervisar cualquier falla. Puedes establecer el destino del informe mediante las directivas report-uri o report-to. Actualmente, report-to no es compatible con todos los navegadores modernos, por lo que se recomienda usar ambos o solo report-uri.

Si algún contenido infringe la CSP, el navegador enviará una denuncia al destino configurado. Asegúrate de tener una aplicación configurada en este destino que controle estos informes.

Define la CSP en un encabezado HTTP

Una CSP se puede definir en una metaetiqueta de la siguiente manera:

<meta http-equiv="Content-Security-Policy" content="script-src 'none'">

Sin embargo, si es posible, debes definir una CSP en un encabezado de respuesta HTTP. Una inyección antes de la metaetiqueta omitirá la CSP. Además, frame-ancestors, sandbox y los informes no son compatibles con las CSP de metaetiquetas.

Asegúrate de que la CSP sea retrocompatible

No todos los navegadores admiten nonces o hashes de la CSP, por lo que se recomienda agregar unsafe-inline como resguardo para los navegadores que no cumplan con las políticas. Si el navegador admite nonces y hashes, se ignorará unsafe-inline.

Del mismo modo, strict-dynamic no es compatible con todos los navegadores. Se recomienda establecer una lista de entidades permitidas como resguardo para los navegadores que no cumplan con los requisitos. Se ignorará la lista de entidades permitidas en los navegadores compatibles con strict-dynamic.

Cómo desarrollar una CSP estricta

A continuación, se muestra un ejemplo del uso de una CSP estricta con una política basada en nonce.

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 sería cualquier cadena base64 generada del servidor cada vez que se carga la página. unsafe-inline y https: se ignoran en los navegadores modernos debido a nonce y strict-dynamic. Para obtener más información sobre la adopción de una CSP estricta, consulta la guía de CSP estricta.

Puedes verificar un CSP para detectar posibles evasiones con Lighthouse y CSP Evaluator. Si deseas probar una CSP nueva sin el riesgo de dañar las páginas existentes, define la CSP en modo de solo informes con Content-Security-Policy-Report-Only como nombre del encabezado. Esto enviará incumplimientos de la CSP a todos los destinos de informes que hayas configurado con report-to y report-uri, pero, en realidad, no aplicará la CSP.