Skip to content

Tutorial para Agregar CSP a una Aplicación Web

En el siguiente articulo estaremos viendo como aplicar los Content security policy(CSP) a para mejorar la seguridad de nuestra aplicacion hecha en Angular, pero antes de profundizar en los detalles tecnicos veamo un poco sobre que son los CSP y porque es importante tenerlos configurados en nuestras aplicaciones web.

¿Que son los Políticas de Seguridad de Contenido?

Las politicas de seguridad de contenido son una capaa de seguridad que permiten a los navegadores detectar y evitar algunos ataques, los mas famosos el XSS y los ataques de inyeccion de datos. En dichos ataques normalmente se busca desde el robo de datos de los usuarios y distorcion del contenido del sitio web, hasta distrubicion de malware.

¿Porque son importantes los CSP?

Las politicas CSP nos permiten evitar que nuestro sitio web sea vulnerables a los ataques mas comunes donde el atacante puede insertar algun codigo malisioso en nuestra pagina. Cuando tenemo una configuracion adecuada de dichas politicas podemos limitar las fuentes de donde ejecutamos funcionalidades y recibimos distinto tipos de contenidos.

Dicho lo anterior, al tener estas limitaciones podemos reducir considerablemente lo ataques XSS o quizas por completo.

¿Como aplicar CSP en una aplicacion web?

Tenemos dos formas de agregar las CSP a nuestra pagina web, la primera es agregando una etiqueta de metadata(<meta>) dentro de la etiqueta <head> de nuestra pagina. La sintaxis seria de la siguiente forma:

<meta
  http-equiv="Content-Security-Policy"
  content="<policy-directive>; <policy-directive>" />

Ejemplo de configuracion de CSP usando etiqueta de metadata:

<meta
  http-equiv="Content-Security-Policy"
  content="default-src 'self' example.com *.example.com" />

La segunda forma es agregando dicha configuracion en los HTTP headers, agregando un header con nombre de «Content-Security-Policy» con la siguiente sintaxis:

Content-Security-Policy: <policy-directive>; <policy-directive>;

Ejemplo configuracion de CSP en header:

Content-Security-Policy: default-src 'self' example.com *.example.com;

Directivas de CSP

En un encabezado de Política de Seguridad de Contenido, se emplean las directivas CSP para determinar los orígenes permitidos para la carga de diferentes tipos de recursos. Así, script-src habilita a los desarrolladores a especificar qué fuentes de scripts pueden ejecutarse en un sitio, font-src regula de qué orígenes se pueden cargar las fuentes tipográficas y style-src regula de que origines se puede cargar y aplicar estilos en nuestra pagina.

En el contenido este articulo estaremos viendo algunas directivas mas utilizadas, pero en el siguiente enlace tienes una lista de todas las que puedes utilizar y su descripciones: Directivas CSP.

Directivas mas utilizadas

  • default-src: Define los orígenes predeterminados para cargar recursos. Si no se especifica una directiva para un tipo de recurso específico, esta actúa como la configuración por defecto.
    • Ejemplo: default-src 'self';
  • script-src: Especifica los orígenes válidos para los scripts. Esta directiva ayuda a prevenir ataques de inyección de scripts.
    • Ejemplo: script-src 'self' https://apis.google.com;
  • style-src: Controla los orígenes de los cuales se pueden cargar hojas de estilo. Ayuda a evitar la inyección de CSS no deseado.
    • Ejemplo: style-src 'self' 'unsafe-inline';
  • img-src: Define los orígenes de donde se pueden cargar imágenes. Se utiliza para evitar la carga de imágenes de sitios no autorizados.
    • Ejemplo: img-src 'self' https://images.example.com;
  • connect-src: Limita los orígenes a los cuales el sitio puede conectarse mediante solicitudes AJAX, WebSockets y otras.
    • Ejemplo: connect-src 'self' https://api.example.com;
  • font-src: Especifica los orígenes de donde se pueden cargar fuentes. Es crucial para controlar las fuentes que se utilizan en el sitio web.
    • Ejemplo: font-src 'self' https://fonts.gstatic.com;
  • object-src: Determina los orígenes de los cuales se pueden cargar plugins, como , o .
    • Ejemplo: object-src 'none';
  • media-src: Define los orígenes de los cuales se pueden cargar medios audio y video.
    • Ejemplo: media-src 'self';
  • frame-src: Especifica los orígenes que pueden ser embebidos como frames. Es útil para controlar el contenido de terceros que se incrusta en el sitio.
    • Ejemplo: frame-src https://example.com;
  • report-uri / report-to: Especifica dónde enviar los informes de violaciones de la política CSP. Aunque report-uri está obsoleto en favor de report-to, aún es ampliamente soportado.
    • Ejemplo: report-uri /csp-violation-report-endpoint/;

¿Que es CSP Nonce o CSP Estricto?

Un CSP (Content Security Policy) Nonce («number used once») es un mecanismo de seguridad que permite a los desarrolladores especificar listas blancas de fuentes de contenido legítimo, previniendo así ataques de tipo Cross-Site Scripting (XSS). Un nonce es un identificador único que se genera para cada solicitud al servidor. Este identificador se incluye en la política de seguridad de contenido del encabezado HTTP y debe coincidir con un atributo nonce especificado en los elementos de script o estilos inline en el HTML.

De esta manera, solo los scripts o estilos que tengan el atributo nonce coincidente serán ejecutados o aplicados, bloqueando cualquier elemento malicioso inyectado.

CSP Estricto

El CSP Estricto, o CSP en modo estricto, refiere a la aplicación de políticas de seguridad de contenido con reglas más rigurosas, minimizando las posibilidades de ataques XSS. Esto se logra mediante la restricción de ciertas prácticas inseguras, como el uso de scripts inline y eval(), y requiriendo que todo el contenido sea cargado desde fuentes seguras y predefinidas. El CSP Estricto es una estrategia proactiva para asegurar una aplicación web, haciendo mucho más difícil para los atacantes explotar vulnerabilidades XSS.

Utilizando CSP Nonce

Para utilizar un nonce con CSP, primero debes generar un nonce único en tu servidor para cada solicitud. Este nonce se incluye en el encabezado CSP de la respuesta HTTP usando la directiva script-src o style-src y también se agrega a los elementos relevantes en tu HTML.

Header CSP:

Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'

HTML:

<script nonce="EDNnf03nceIOfn39fn3e9h3sdfa">
  // Tu código JavaScript aquí
</script>

Utilizando CSP Hash

El CSP Hash permite especificar hashes de scripts o estilos inline permitidos. En lugar de usar nonces, puedes incluir un hash SHA-256, SHA-384, o SHA-512 del contenido exacto del script o estilo en las directivas script-src o style-src del encabezado CSP. Esto asegura que solo el contenido que coincida exactamente con el hash especificado se ejecute o aplique.

Header CSP:

Content-Security-Policy: script-src 'sha256-xZvra5yX4EjW1a2F5lAysx/7RXtIPL5eV3y0llGO3ME='

HTML:

<script>
  // Este script será bloqueado a menos que su contenido coincida exactamente con el hash especificado.
</script>

Comparacion entre CSP Nonce vs CSP Hash

Caracteristicas de Uso de Nonce

Ventajas:

  • Flexibilidad: El uso de nonces permite una gran flexibilidad, ya que puedes incluir scripts inline y estilos que cambian dinámicamente, generando un nuevo nonce para cada respuesta HTTP. Esto es especialmente útil en aplicaciones web que generan contenido dinámico.
  • Facilidad de implementación: Implementar nonces puede ser más sencillo en entornos donde el contenido se genera o cambia con frecuencia, ya que solo necesitas asegurarte de que el nonce generado coincida entre el encabezado HTTP y los elementos en la página.

Desventajas:

  • Mantenimiento: Puede ser más difícil de mantener en aplicaciones grandes o complejas debido a la necesidad de asegurar que el nonce se genere correctamente y se aplique a todos los elementos relevantes.
  • Riesgo de mal uso: Si el nonce se filtra o se usa incorrectamente, podría ser explotado por un atacante para eludir las restricciones de CSP.

Caracteristicas de Uso de CSP Hash

Ventajas:

  • Seguridad mejorada: Al especificar hashes de contenido exacto, CSP Hash ofrece una capa adicional de seguridad. Solo el contenido que coincide exactamente con el hash predefinido se ejecutará, lo que reduce el riesgo de ataques XSS mediante la inyección de scripts maliciosos.
  • Consistencia: Los hashes proporcionan un método consistente para validar contenido, ideal para aplicaciones que sirven contenido estático o que rara vez cambian los scripts inline o estilos.

Desventajas:

  • Menos flexibilidad: Los hashes son menos flexibles que los nonces, ya que cualquier cambio en el script o estilo inline requiere la generación de un nuevo hash y la actualización del encabezado CSP. Esto puede ser engorroso para el contenido que cambia con frecuencia.
  • Complejidad en la gestión: Para aplicaciones con muchos scripts o estilos inline, mantener una lista actualizada de hashes puede ser complejo y propenso a errores.

Configurar CSP en Headers de Respuesta HTTP desde el Servidor

A continuacion estaremos viendo algunos ejemplos de como agregar la configuracion de los CSP usando los servidores web mas comunes, toma en consideracion que aunque estos son ejemplos muy especificos, pero sin importar el tipo de servidor que este corriendo tu aplicación la implementación debe ser bastante similar.

Ejemplo agregando CSP con servidor ngnix

Para configurar CSP en Nginx, necesitas agregar la directiva add_header en tu archivo de configuración de Nginx (nginx.conf o en el archivo de configuración específico del sitio dentro de /etc/nginx/sites-available/).

server {
    listen 80;
    server_name tu-dominio.com;

    location / {
        add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://apis.google.com";
        ...
    }
}

Este ejemplo establece una política CSP que permite cargar recursos solo desde el mismo origen ('self') y scripts desde el mismo origen así como desde https://apis.google.com.

Ejemplo agregando CSP con servidor Node JS(Express.js)

Para aplicar CSP en una aplicación Node.js utilizando el framework Express, puedes usar el paquete helmet, que es un middleware que ayuda a asegurar tus aplicaciones Express configurando varios headers HTTP. Primero, instala helmet:

npm install helmet

Luego, configura CSP con Helmet en tu aplicación:

const express = require('express');
const helmet = require('helmet');

const app = express();

app.use(helmet.contentSecurityPolicy({
    directives: {
        defaultSrc: ["'self'"],
        scriptSrc: ["'self'", "https://apis.google.com"],
    }
}));

app.get('/', (req, res) => {
    res.send('Hello World!');
});

app.listen(3000, () => {
    console.log('Servidor corriendo en http://localhost:3000');
});

Ejemplo agregando CSP con servidor PHP

Para configurar CSP en PHP, puedes enviar el header Content-Security-Policy directamente usando la función header() antes de enviar cualquier salida al navegador:

<?php
header("Content-Security-Policy: default-src 'self'; script-src 'self' https://apis.google.com");
?>
<!DOCTYPE html>
<html>
<head>
    <title>Página Segura</title>
</head>
<body>
    <h1>Hola Mundo</h1>
</body>
</html>

Una nota importante es que sin importar el tipo de servidor que este ejecutando tu aplicacion web es importante que realices las pruebas necesarias para confirmar que una vez tu CSP configurados no afecte la funcionalidad de dicho sitio.

A continuacion te estare mostrando algunas herramientas que puedes utilizar para validar tu configuracion CSP y evitar introducir errores en tu sitio web.

¿Como evaluar la configuracion de CSP en tu sitio web para evitar errores en produccion?

Existen varias formas que puedes verificar si la configuracion CSP aplicada a tu sitio web no esta probacando ningun error, a continuacion te comparto 4 de las mas utilizadas, comenzando con la mas sencilla.

1. Utilizar las herramientas de desarrollo del navegador

Los navegadores modernos como Chrome, Firefox, y Safari tienen herramientas de desarrollo integradas que te permiten ver los headers de respuesta HTTP, incluyendo el Content Security Policy. Puedes utilizar estas herramientas para asegurarte de que tu servidor esté enviando el CSP esperado.

Además, estas herramientas te mostrarán advertencias y errores si algún recurso está bloqueado por tus políticas CSP, facilitando la identificación de problemas.

Ejemplo de error en de CSP en consola:

2. CSP Evaluator

CSP Evaluator es una herramienta en línea creada por Google que te permite evaluar la seguridad de tus políticas CSP. Solo necesitas ingresar tu política CSP, y la herramienta te proporcionará un análisis detallado, señalando posibles problemas de seguridad y recomendaciones para mejorar tu CSP.

Image de CSP evaluator

3. Extensiones del navegador

Existen varias extensiones de navegador diseñadas específicamente para trabajar con CSP, como «CSP Tester» para Google Chrome. Estas extensiones te permiten experimentar con diferentes políticas CSP directamente desde tu navegador, facilitando la identificación de problemas y la optimización de tu configuración.

Imagen de CSP Tester extension de Chrome.

4. Mozilla Observatory

Mozilla Observatory es una herramienta en línea que analiza la seguridad de tu sitio web, incluyendo la evaluación de tu CSP. Proporciona puntuaciones basadas en varias métricas de seguridad y ofrece sugerencias para mejorar la configuración de seguridad de tu sitio.

Conclusion

En este articulo hemos abordado el como los CSP nos permiten mejorar la seguridad de nuestro sitio web restringiendo el contenido que cargamos y limitando la posibilidades de que un atacante puede insertar codigo malicioso en nuestra pagina web.

Tambien podemos observar en cuales casos es conveniente agregar una capa de seguridad utilizando lo CSP Nonce y CSP Hash, ademas de algunos ejemplos de como agregar dichas configuraciones usando algunos de los servidores mas comunes.

Por ultimo, es importante recarcar que debemos validar nuestras configuraciones CSP, si bien es cierto que nuestro sitio debe ser seguro, debemos tener cuidado de afectar la funcionalidad basica del mismo agregando politicas muy restrictivas que puedan crear errores en producción.

Espero que les haya gustado el contenido del articulo.

Picture of Yeison Lapaix
Yeison Lapaix
Hola!, Soy Yeison Lapaix un desarrollador Full Stack .Net con más de 10 años de experiencia en el desarrollo de aplicaciones web con ASP.NET Core, MVC, C#, JavaScript, Oracle DB y SQL Server. Tengo buena experiencia en la creación de API web RESTful con .Net Core y aplicaciones front-end con Angular, Vue JS, jQuery, HTML5 y CSS. Trabajo competente con principios OOP y patrones de diseño, principios SOLID y experiencia con entornos de desarrollo ágiles. Me considero un desarrollador entusiasta que busca mejoras continuas para ser mejor cada día.

TABLE OF CONTENTS

Yeison Lapaix – Full Stack Developer | .NET | Angular | Systems Engineer | Technology Enthusiast