Cómo proteger las aplicaciones Node.js con una política de seguridad de contenido

Índice
  1. Introducción
  • Prerrequisitos
  • Paso 1: Configuración del proyecto de demostración
  • Paso 2: Implementación de un CSP básico
  • Paso 3: Solución de las infracciones de las políticas
    1. Permitir las hojas de estilo
    2. Permitir las fuentes de imágenes
    3. Permitir la incrustación de YouTube
    4. Permitir los archivos de fuentes
    5. Permitir el script Vue.js
  • Paso 4: Manejo de fuentes en línea
    1. Opción 1: usar un hash
    2. Opción 2: usar un Nonce
  • Paso 5: Seguimiento de las infracciones
  • Paso 6 — Publicación de la política final
  • El autor seleccionó a la Free Software Foundation para recibir una donación como parte del programa Write for DOnations.

    Introducción

    Cuando el navegador carga una página, ejecuta una gran cantidad de código para reproducir el contenido. El código puede tener el mismo origen que el documento raíz o un origen diferente. De forma predeterminada, el navegador no distingue entre ambos y ejecuta cualquier código solicitado por una página, independientemente de la fuente. Los atacantes utilizan este exploit para inyectar de forma maliciosa secuencias de comandos en la página, que luego se ejecutan porque el navegador no tiene forma de determinar si el contenido es dañino. Estas situaciones son en las que una Política de seguridad de contenido (CSP) puede brindar protección.

    Un CSP es un encabezado HTTP que proporciona una capa adicional de seguridad contra ataques de inyección de código, como secuencias de comandos entre sitios (XSS), clickjacking y otros ataques similares. Facilita la creación de una “lista de permitidos” de contenido confiable y bloquea la ejecución de código de fuentes que no están presentes en la lista de permitidos. También informa sobre cualquier violación de políticas a una URL de su elección, para que pueda mantenerse al tanto de posibles ataques de seguridad.

    Con el encabezado CSP, puede especificar fuentes aprobadas para el contenido de su sitio que el navegador puede cargar. Se bloqueará la ejecución de cualquier código que no provenga de las fuentes aprobadas, lo que hace que sea considerablemente más difícil para un atacante inyectar contenido y extraer datos.

    En este tutorial, revisará las diferentes protecciones que ofrece el encabezado CSP implementando una en una aplicación Node.js de ejemplo. También recopilará informes JSON de violaciones de CSP para detectar problemas y solucionar vulnerabilidades rápidamente.

    Prerrequisitos

    Para seguir este tutorial, necesitarás lo siguiente:

    • Una versión reciente de Node.js instalada en su equipo. Siga los pasos del tutorial Cómo instalar Node.js correspondiente a su sistema operativo para configurar un entorno de desarrollo de Node.js.

    También debe utilizar una versión reciente del navegador, preferiblemente Chrome, ya que tiene la mejor compatibilidad con las directivas de nivel 3 de CSP al momento de escribir este artículo (noviembre de 2020). Además, asegúrese de deshabilitar cualquier extensión de terceros mientras prueba la implementación de CSP para que no interfieran con los informes de infracciones que se muestran en la consola.

    Paso 1: Configuración del proyecto de demostración

    Para demostrar el proceso de creación de una Política de seguridad de contenido, trabajaremos en todo el proceso de implementación de una para este proyecto de demostración. Es un sitio web de una sola página con una variedad de contenido que se aproxima a un sitio web o aplicación típicos. Incluye una pequeña aplicación Vue.js, incrustaciones de YouTube y algunas imágenes provenientes de Unsplash. También utiliza fuentes de Google y el marco Bootstrap, que se carga a través de una red de distribución de contenido (CDN).

    En este paso, configurará el proyecto de demostración en su servidor de prueba o máquina local y lo verá en su navegador.

    Primero, clone el proyecto en su sistema de archivos usando el siguiente comando:

    1. git clone https://github.com/do-community/csp-demo

    Una vez configurado el directorio del proyecto, cámbielo con el siguiente comando:

    1. cd csp-demo

    A continuación, instale las dependencias especificadas en el package.jsonarchivo con el siguiente comando. Utilice el expresspaquete para configurar el servidor web, mientras que nodemonayuda a reiniciar automáticamente la aplicación de nodo cuando detecta cambios de archivo en el directorio:

    1. npm install

    Una vez que haya instalado las dependencias, ingrese el siguiente comando para iniciar el servidor web en el puerto 5500:

    1. npm start

    Ahora puede visitar your_server_ip:5500o localhost:5500en su navegador para ver la página de demostración. Encontrará el texto ¡Hola mundo!, una inserción de YouTube y algunas imágenes en la página.

    En la siguiente sección, implementaremos una política de CSP que cubra solo las protecciones más básicas. Luego, desarrollaremos esa política en las secciones siguientes a medida que descubramos todos los recursos legítimos que debemos permitir en la página.

    Paso 2: Implementación de un CSP básico

    Vamos a escribir una política CSP que restrinja las fuentes, imágenes, scripts, estilos e incrustaciones a aquellos que se originan únicamente en el host actual. El siguiente es el encabezado de respuesta que logra esto:

    Content-Security-Policy: default-src 'self'; font-src 'self'; img-src 'self'; script-src 'self'; style-src 'self'; frame-src 'self';

    A continuación se muestra una explicación de las directivas de política en este encabezado:

    • font-srcdefine las fuentes desde donde se pueden cargar las fuentes.
    • img-srcdefine las fuentes desde las que se permite la carga de imágenes.
    • script-srccontrola cualquier privilegio de carga de scripts en una página web.
    • style-srcEs la directiva para permitir fuentes de hojas de estilo.
    • frame-srcDefine las fuentes permitidas para incrustaciones de marcos. (Quedó obsoleto en el nivel 2 de CSP, pero se restableció en el nivel 3).
    • default-srcdefine una política de respaldo para ciertas directivas si no se especifican explícitamente en el encabezado. Aquí hay una lista completa de las directivas a las que se recurre default-src.

    En este ejemplo, a todas las directivas especificadas se les asigna la 'self'palabra clave en su lista de fuentes. Esto indica que solo se debe permitir la ejecución de recursos del host actual (incluido el esquema de URL y el número de puerto). Por ejemplo, script-src 'self'permite la ejecución de scripts desde el host actual, pero bloquea todas las demás fuentes de scripts.

    Sigamos adelante y agreguemos el encabezado a nuestro proyecto Node.js.

    Deje su aplicación ejecutándose y abra una nueva ventana de terminal para trabajar con su server.jsarchivo:

    1. nano server.js

    A continuación, agregue el encabezado CSP del ejemplo en una capa de middleware de Express. Esto garantiza que incluya el encabezado en cada respuesta del servidor:

    servidor.js

    const express = require('express');const bodyParser = require('body-parser');const path = require('path');const app = express();app.use(function (req, res, next) {  res.setHeader(    'Content-Security-Policy',    "default-src 'self'; font-src 'self'; img-src 'self'; script-src 'self'; style-src 'self'; frame-src 'self'"  );  next();});app.use(bodyParser.json());app.use(express.static(path.join(__dirname)));app.get('/', (req, res) = {  res.sendFile(path.join(__dirname + '/index.html'));});const server = app.listen(process.env.PORT || 5500, () = {  const { port } = server.address();  console.log(`Server running on PORT ${port}`);});

    Guarda el archivo y vuelve a cargar el proyecto en tu navegador. Notarás que la página está completamente rota.

    Nuestro encabezado CSP funciona como se esperaba y se ha bloqueado la carga de todas las fuentes externas que incluimos en la página porque violan la política definida. Sin embargo, esta no es la forma ideal de probar una política completamente nueva, ya que puede dañar un sitio web cuando se producen violaciones.

    Por eso Content-Security-Policy-Report-Onlyexiste el encabezado. Puedes usarlo en lugar de Content-Security-Policypara evitar que el navegador aplique la política, a la vez que sigues informando de las infracciones que se producen, lo que significa que puedes perfeccionar la política sin poner en riesgo tu sitio. Una vez que estés conforme con tu política, puedes volver al encabezado de aplicación para que se activen las protecciones.

    Continúe y reemplace el Content-Security-Policyencabezado con Content-Security-Policy-Report-Onlyen su server.jsarchivo:

    1. nano server.js

    Añade el siguiente código resaltado:

    servidor.js

    . . .app.use(function (req, res, next) {  res.setHeader(    'Content-Security-Policy-Report-Only',    "default-src 'self'; font-src 'self'; img-src 'self'; script-src 'self'; style-src 'self'; frame-src 'self'"  );  next();});. . .

    Guarde el archivo y vuelva a cargar la página en su navegador. La página vuelve a funcionar, pero la consola del navegador sigue informando las infracciones de CSP. Cada infracción tiene el prefijo [Report Only]para indicar que la política no se aplica.

    En esta sección, creamos la implementación inicial de nuestro CSP y la configuramos en modo de solo informes para que podamos refinarla sin provocar fallas en el sitio. En la siguiente sección, solucionaremos las infracciones que se generaron a través de nuestro CSP inicial.

    Paso 3: Solución de las infracciones de las políticas

    La política que implementamos en la sección anterior desencadenó varias violaciones porque restringimos todos los recursos solo al origen; sin embargo, tenemos varios activos de terceros en la página.

    Las dos formas de solucionar las infracciones de CSP son: aprobar las fuentes en la política o eliminar el código que desencadena las infracciones. Dado que los recursos legítimos desencadenan todas las infracciones, en esta sección nos concentraremos principalmente en la primera opción.

    Abra la consola de su navegador. Se mostrarán todas las infracciones actuales del CSP. Solucionemos cada uno de estos problemas.

    Permitir las hojas de estilo

    Las dos primeras infracciones en la consola son de las fuentes de Google y las hojas de estilo de Bootstrap, que estás cargando desde https://fonts.googleapis.comy https://cdn.jsdelivr.netrespectivamente. Puedes permitirlas en la página mediante la style-srcdirectiva:

    style-src 'self' https://fonts.googleapis.com https://cdn.jsdelivr.net;

    Esto especifica que los archivos CSS del host de origen, https://fonts.googleapis.comy https://cdn.jsdelivr.net, deben ejecutarse en la página. Esta política es bastante amplia, porque permite cualquier hoja de estilo de los dominios de la lista de permitidos (no solo los que estás usando actualmente).

    Podemos ser más específicos utilizando el archivo o directorio exacto que nos gustaría permitir:

    style-src 'self' https://fonts.googleapis.com https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css;

    Ahora, solo permitirá que se ejecute la hoja de estilo exacta y especificada. Bloqueará todas las demás hojas de estilo, incluso si se originan en https://cdn.jsdelivr.net.

    Puede actualizar el encabezado CSP de la siguiente manera con la style-srcdirectiva actualizada. Cuando vuelva a cargar la página, se habrán resuelto ambas infracciones:

    servidor.js

    . . .app.use(function (req, res, next) {  res.setHeader(    'Content-Security-Policy-Report-Only',    "default-src 'self'; font-src 'self'; img-src 'self'; script-src 'self'; style-src 'self' https://fonts.googleapis.com https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css; frame-src 'self';"  );  next();});. . .

    Permitir las fuentes de imágenes

    Las imágenes que estás usando en la página provienen de una única fuente: https://images.unsplash.com. Permitámoslo mediante la img-srcdirectiva de la siguiente manera:

    servidor.js

    . . .app.use(function (req, res, next) {  res.setHeader(    'Content-Security-Policy-Report-Only',    "default-src 'self'; font-src 'self'; img-src 'self' https://images.unsplash.com; script-src 'self'; style-src 'self' https://fonts.googleapis.com https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css; frame-src 'self'"  );  next();});. . .

    Permitir la incrustación de YouTube

    Puede permitir fuentes válidas para contextos de navegación anidados, que utilizan elementos como iframe, mediante la frame-srcdirectiva. Si esta directiva no está presente, el navegador buscará la child-srcdirectiva y, posteriormente, recurrirá a default-srcella.

    Nuestra política actual limita las incrustaciones de fotogramas al host de origen. Agreguemos contenido https://www.youtube.coma la lista de permitidos para que el CSP no bloquee la carga de incrustaciones de YouTube una vez que apliquemos la política:

    frame-src 'self' https://www.youtube.com;

    Tenga en cuenta que el wwwsubdominio es importante aquí. Si tiene una incrustación de https://youtube.com, se bloqueará de acuerdo con esta política a menos que también la agregue https://youtube.coma la lista de permitidos:

    frame-src 'self' https://www.youtube.com https://youtube.com;

    Aquí está el encabezado CSP actualizado. Cambie la frame-srcdirectiva de la siguiente manera:

    servidor.js

    . . .app.use(function (req, res, next) {  res.setHeader(    'Content-Security-Policy-Report-Only',    "default-src 'self'; font-src 'self'; img-src 'self' https://images.unsplash.com; script-src 'self'; style-src 'self' https://fonts.googleapis.com https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css; frame-src 'self' https://www.youtube.com https://youtube.com;"  );  next();});. . .

    Permitir los archivos de fuentes

    La hoja de estilos de fuentes de Google contiene referencias a varios archivos de fuentes de https://fonts.gstatic.com. Verá que estos archivos actualmente infringen la font-srcpolítica definida (actualmente 'self'), por lo que debe tenerlos en cuenta en su política revisada:

    font-src 'self' https://fonts.gstatic.com;

    Actualice la font-srcdirectiva en el encabezado CSP de la siguiente manera:

    servidor.js

    . . .app.use(function (req, res, next) {  res.setHeader(    'Content-Security-Policy-Report-Only',    "default-src 'self'; font-src 'self' https://fonts.gstatic.com; img-src 'self' https://images.unsplash.com; script-src 'self'; style-src 'self' https://fonts.googleapis.com https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css; frame-src 'self' https://www.youtube.com https://youtube.com;"  );  next();});. . .

    Una vez que vuelva a cargar la página, la consola ya no informará violaciones en los archivos de fuentes de Google.

    Permitir el script Vue.js

    Un script de Vue.js cargado a través de una CDN está mostrando el texto ¡Hola mundo! en la parte superior de la página. Permitiremos su ejecución en la página a través de la script-srcdirectiva. Como se mencionó anteriormente, es importante ser específico al permitir fuentes de CDN para no abrir nuestro sitio a otros posibles scripts maliciosos que estén alojados en ese dominio.

    script-src 'self' https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.min.js;

    En este ejemplo, solo permites que se ejecute en la página el script exacto en esa URL. Si quieres cambiar entre compilaciones de desarrollo y producción, también tendrás que agregar la otra URL del script a la lista de permitidos, o puedes permitir todos los recursos presentes en la /distubicación para cubrir ambos casos a la vez:

    script-src 'self' https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/;

    Aquí está el encabezado CSP actualizado con los cambios relevantes:

    servidor.js

    . . .app.use(function (req, res, next) {  res.setHeader(    'Content-Security-Policy-Report-Only',    "default-src 'self'; font-src 'self' https://fonts.gstatic.com; img-src 'self' https://images.unsplash.com; script-src 'self' https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/; style-src 'self' https://fonts.googleapis.com https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css; frame-src 'self' https://www.youtube.com https://youtube.com;"  );  next();});. . .

    En este punto, hemos permitido con éxito todos los archivos y scripts externos de los que depende nuestra página. Pero aún tenemos una infracción de CSP más que resolver debido a la presencia de un script en línea en la página. Exploraremos algunas soluciones a este problema en la siguiente sección.

    Paso 4: Manejo de fuentes en línea

    Si bien es posible aprobar código en línea (como código JavaScript en una scriptetiqueta) dentro de un CSP usando la 'unsafe-inline'palabra clave, no se recomienda porque aumenta en gran medida el riesgo de un ataque de inyección de código.

    Esta política de ejemplo permite la ejecución de cualquier script en línea en la página, pero esto no es seguro por las razones mencionadas anteriormente.

    script-src 'self' 'unsafe-inline' https://unpkg.com/vue@3.0.2/dist/;

    La mejor forma de evitar su uso unsafe-inlinees mover el código en línea a un archivo externo y hacer referencia a él de esa manera. Este es un mejor enfoque para el almacenamiento en caché, la minimización y la capacidad de mantenimiento, y también hace que el CSP sea más fácil de modificar en el futuro.

    Sin embargo, si es absolutamente necesario utilizar código en línea, hay dos formas principales de agregarlo a su lista de permitidos de forma segura.

    Opción 1: usar un hash

    Este método requiere que calcules un hash SHA basado en el script en sí y luego lo agregues a la script-srcdirectiva. En las versiones recientes de Chrome, ni siquiera necesitas generar el hash tú mismo, ya que ya está incluido en el error de violación de CSP en la consola:

    [Report Only] Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' https://unpkg.com/vue@3.0.2/dist/". Either the 'unsafe-inline' keyword, a hash ('sha256-INJfZVfoUd61ITRFLf63g+S/NJAfswGDl15oK0iXgYM='), or a nonce ('nonce-...') is required to enable inline execution.

    La sección resaltada aquí es el hash SHA256 exacto que necesitaría agregar a la script-srcdirectiva para permitir la ejecución del script en línea específico que desencadenó la violación.

    Copia el hash y agrégalo a tu CSP de la siguiente manera:

    script-src 'self' https://unpkg.com/vue@3.0.2/dist/ 'sha256-INJfZVfoUd61ITRFLf63g+S/NJAfswGDl15oK0iXgYM=';

    La desventaja de este enfoque es que si el contenido del script cambia, el hash generado será diferente, lo que provocará una violación.

    Opción 2: usar un Nonce

    La segunda forma de permitir la ejecución de código en línea es mediante un nonce. Se trata de cadenas aleatorias que se pueden utilizar para permitir un bloque completo de código independientemente de su contenido.

    A continuación se muestra un ejemplo de un valor nonce en uso:

    script-src 'self' https://unpkg.com/vue@3.0.2/dist/ 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'

    El valor del nonce en el CSP debe coincidir con el nonceatributo en el script:

    script nonce="EDNnf03nceIOfn39fn3e9h3sdfa"  // Some inline code/script

    Los nonces deben ser indescifrables y deben generarse dinámicamente cada vez que se carga la página para que un atacante no pueda usarlos para ejecutar un script malicioso. Si decide implementar esta opción, puede usar el cryptopaquete para generar un nonce de la siguiente manera:

    const crypto = require('crypto');let nonce = crypto.randomBytes(16).toString('base64');

    Optaremos por el método hash en este tutorial porque es más práctico para nuestro caso de uso.

    Actualice la script-srcdirectiva en su encabezado CSP para incluir el hash SHA256 del único script en línea como se muestra a continuación:

    servidor.js

    . . .app.use(function (req, res, next) {  res.setHeader(    'Content-Security-Policy-Report-Only',    "default-src 'self'; font-src 'self' https://fonts.gstatic.com; img-src 'self' https://images.unsplash.com; script-src 'self' https://unpkg.com/vue@3.0.2/dist/ 'sha256-INJfZVfoUd61ITRFLf63g+S/NJAfswGDl15oK0iXgYM='; style-src 'self' https://fonts.googleapis.com https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css; frame-src 'self' https://www.youtube.com https://youtube.com;"  );  next();});. . .

    Esto elimina el error de violación de CSP final que el script en línea activa desde la consola.

    En la siguiente sección, monitorearemos los efectos de nuestro CSP en un entorno de producción.

    Paso 5: Seguimiento de las infracciones

    Una vez que tenga su CSP en funcionamiento, es necesario vigilar sus efectos una vez que esté en uso. Por ejemplo, si olvida permitir una fuente legítima en producción o cuando un atacante intenta explotar un vector de ataque XSS (que debe identificar y detener de inmediato).

    Sin algún tipo de informe activo, no hay forma de saber de estos eventos. Por eso report-toexiste la directiva. Especifica una ubicación a la que el navegador debe enviar un informe de infracción en formato JSON, en caso de que tenga que tomar medidas en función del CSP.

    Para utilizar esta directiva, debe agregar un encabezado adicional para especificar un punto final para la API de informes:

    Report-To: {"group":"csp-endpoint","max_age":10886400,"endpoints":[{"url":"http://your_server_ip:5500/__cspreport__"}],"include_subdomains":true}

    Una vez configurado esto, especifique el nombre del grupo en la report-todirectiva de la siguiente manera:

    report-to csp-endpoint;

    Aquí se muestra la parte actualizada del server.jsarchivo con los cambios. Asegúrese de reemplazar el your_server_ipmarcador de posición en el Report-Toencabezado con la dirección IP real de su servidor:

    servidor.js

    . . .app.use(function (req, res, next) {  res.setHeader(    'Report-To',    '{"group":"csp-endpoint","max_age":10886400,"endpoints":[{"url":"https://your_server_ip:5500/__cspreport__"}],"include_subdomains":true}'  );  res.setHeader(    'Content-Security-Policy-Report-Only',    "default-src 'self'; font-src 'self' https://fonts.gstatic.com; img-src 'self' https://images.unsplash.com; script-src 'self' https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/ 'sha256-INJfZVfoUd61ITRFLf63g+S/NJAfswGDl15oK0iXgYM='; style-src 'self' https://fonts.googleapis.com https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css; frame-src 'self' https://www.youtube.com https://youtube.com; report-to csp-endpoint;"  );  next();});. . .

    La report-todirectiva pretende reemplazar a la report-uridirectiva ahora obsoleta, pero la mayoría de los navegadores aún no la admiten (a fecha de noviembre de 2020). Por lo tanto, para garantizar la compatibilidad con los navegadores actuales y, al mismo tiempo, la compatibilidad con las futuras versiones de navegadores, debe especificar tanto report-uriy report-toen su CSP. Si se admite la última, se ignorará la primera:

    servidor.js

    . . .app.use(function (req, res, next) {  res.setHeader(    'Report-To',    '{"group":"csp-endpoint","max_age":10886400,"endpoints":[{"url":"https://your_server_ip:5500/__cspreport__"}],"include_subdomains":true}'  );  res.setHeader(    'Content-Security-Policy-Report-Only',    "default-src 'self'; font-src 'self' https://fonts.gstatic.com; img-src 'self' https://images.unsplash.com; script-src 'self' https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/ 'sha256-INJfZVfoUd61ITRFLf63g+S/NJAfswGDl15oK0iXgYM='; style-src 'self' https://fonts.googleapis.com https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css; frame-src 'self' https://www.youtube.com https://youtube.com; report-to csp-endpoint; report-uri /__cspreport__;"  );  next();});. . .

    La /__cspreport__ruta también debe existir en el servidor; agregue esto a su archivo de la siguiente manera:

    servidor.js

    . . .app.get('/', (req, res) = {  res.sendFile(path.join(__dirname + '/index.html'));});app.post('/__cspreport__', (req, res) = {  console.log(req.body);});. . .

    Algunos navegadores envían la Content-Typecarga útil del informe como application/csp-report, mientras que otros utilizan application/json. Si report-tose admite la directiva, Content-Typedebería ser application/reports+json.

    Para tener en cuenta todos los Content-Typevalores posibles, debes configurar algunas configuraciones en tu servidor express:

    servidor.js

    . . .app.use(  bodyParser.json({    type: ['application/json', 'application/csp-report', 'application/reports+json'],  }));. . .

    En este punto, cualquier violación de CSP se enviará a la /__cspreport__ruta y posteriormente se registrará en la terminal.

    Puede probarlo agregando un recurso de una fuente que no sea compatible con el CSP actual o modificando el script en línea en el index.htmlarchivo como se muestra a continuación:

    índice.html

    . . .script  new Vue({    el: '#vue',    render(createElement) {      return createElement('h1', 'Hello World!');    },  });  console.log("Hello")/script. . .

    Esto provocará una violación porque el hash del script ahora es diferente de lo que incluiste en el encabezado CSP.

    A continuación se muestra un informe de infracción típico de un navegador que utiliza report-uri:

    {  'csp-report': {    'document-uri': 'http://localhost:5500/',    referrer: '',    'violated-directive': 'script-src-elem',    'effective-directive': 'script-src-elem',    'original-policy': "default-src 'self'; font-src 'self' https://fonts.gstatic.com; img-src 'self' https://images.unsplash.com; script-src 'self' https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/ 'sha256-INJfZVfoUd61ITRFLf63g+S/NJAfswGDl15oK0iXgYM='; style-src 'self' https://fonts.googleapis.com https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css; frame-src 'self' https://www.youtube.com https://youtube.com; report-uri /__cspreport__;",    disposition: 'report',    'blocked-uri': 'inline',    'line-number': 58,    'source-file': 'http://localhost:5500/',    'status-code': 200,    'script-sample': ''  }}

    Las partes de este informe son:

    • document-uri:La página en la que ocurrió la violación.
    • referrer:El referente de la página.
    • blocked-uri:El recurso que violó la política de la página (un inlinescript en este caso).
    • line-number:El número de línea donde comienza el código en línea.
    • violated-directive:La directiva específica que se violó. ( script-src-elemen este caso, que retrocede a script-src.)
    • original-policy:La política completa de la página.

    Si el navegador admite la report-todirectiva, la carga útil debería tener una estructura similar a la que se muestra a continuación. Observe cómo se diferencia de la report-uricarga útil, aunque sigue conteniendo la misma información:

    [{"age": 16796,"body": {"blocked-uri": "https://vimeo.com","disposition": "enforce","document-uri": "https://localhost:5500/","effective-directive": "frame-src","line-number": 58,    'original-policy': "default-src 'self'; font-src 'self' https://fonts.gstatic.com; img-src 'self' https://images.unsplash.com; script-src 'self' https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/ 'sha256-INJfZVfoUd61ITRFLf63g+S/NJAfswGDl15oK0iXgYM='; style-src 'self' https://fonts.googleapis.com https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css; frame-src 'self' https://www.youtube.com https://youtube.com; report-uri /__cspreport__;","referrer": "","script-sample": "","sourceFile": "https://localhost:5500/","violated-directive": "frame-src"},"type": "csp","url": "https://localhost:5500/","user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"}]

    Nota : La report-todirectiva solo se admite en contextos seguros, lo que significa que debe configurar su servidor Express con un certificado HTTPS válido; de lo contrario, no podrá probarlo ni usarlo.

    En esta sección, configuramos correctamente la supervisión de CSP en nuestro servidor para poder detectar y solucionar problemas rápidamente. Sigamos adelante y finalicemos este tutorial aplicando la política final en el siguiente paso.

    Paso 6 — Publicación de la política final

    Una vez que esté seguro de que su CSP está configurado correctamente (idealmente después de dejarlo en producción durante algunos días o semanas en modo de solo informes), puede aplicarlo cambiando el encabezado de CSP de Content-Security-Policy-Report-Onlya Content-Security-Policy.

    Además de informar las violaciones, esto evitará que se ejecuten recursos no autorizados en la página, lo que generará una experiencia más segura para sus visitantes.

    Aquí está la versión final del server.jsarchivo:

    servidor.js

    const express = require('express');const bodyParser = require('body-parser');const path = require('path');const app = express();app.use(function (req, res, next) {  res.setHeader(    'Report-To',    '{"group":"csp-endpoint","max_age":10886400,"endpoints":[{"url":"http://your_server_ip:5500/__cspreport__"}],"include_subdomains":true}'  );  res.setHeader(    'Content-Security-Policy',    "default-src 'self'; font-src 'self' https://fonts.gstatic.com; img-src 'self' https://images.unsplash.com; script-src 'self' https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/ 'sha256-INJfZVfoUd61ITRFLf63g+S/NJAfswGDl15oK0iXgYM='; style-src 'self' https://fonts.googleapis.com https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css; frame-src 'self' https://www.youtube.com https://youtube.com; report-to csp-endpoint; report-uri /__cspreport__;"  );  next();});app.use(  bodyParser.json({    type: [      'application/json',      'application/csp-report',      'application/reports+json',    ],  }));app.use(express.static(path.join(__dirname)));app.get('/', (req, res) = {  res.sendFile(path.join(__dirname + '/index.html'));});app.post('/__cspreport__', (req, res) = {  console.log(req.body);});const server = app.listen(process.env.PORT || 5500, () = {  const { port } = server.address();  console.log(`Server running on PORT ${port}`);});

    Compatibilidad con navegadores El encabezado CSP es compatible con todos los navegadores, con excepción de Internet Explorer, que utiliza el X-Content-Security-Poli

    SUSCRÍBETE A NUESTRO BOLETÍN 
    No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

    Subir

    Este sitio web utiliza cookies para mejorar tu experiencia mientras navegas por él. Este sitio web utiliza cookies para mejorar tu experiencia de usuario. Al continuar navegando, aceptas su uso. Mas informacion