Tutorial para Agregar CSP a una Aplicacion Web

En el siguiente articulo estaremos viendo como aplicar los Content Security Policy (CSP) para mejorar la seguridad de nuestra aplicacion hecha en Angular, pero antes de profundizar en los detalles tecnicos veamos un poco sobre que son los CSP y por que es importante tenerlos configurados en nuestras aplicaciones web.
Que son las Politicas de Seguridad de Contenido?
Las politicas de seguridad de contenido son una capa 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 distorsion del contenido del sitio web, hasta distribucion de malware.
Por que son importantes los CSP?
Las politicas CSP nos permiten evitar que nuestro sitio web sea vulnerable a los ataques mas comunes donde el atacante puede insertar algun codigo malicioso en nuestra pagina. Cuando tenemos una configuracion adecuada de dichas politicas podemos limitar las fuentes desde donde ejecutamos funcionalidades y recibimos distintos tipos de contenidos.
Dicho lo anterior, al tener estas limitaciones podemos reducir considerablemente los ataques XSS, o quizas por completo.
Como aplicar CSP en una aplicacion web?
Tenemos dos formas de agregar los 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 Content-Security-Policy con la siguiente sintaxis:
Content-Security-Policy: <policy-directive>; <policy-directive>;
Ejemplo de configuracion de CSP en header:
Content-Security-Policy: default-src 'self' example.com *.example.com;
Directivas de CSP
En un encabezado de Politica de Seguridad de Contenido, se emplean las directivas CSP para determinar los origenes permitidos para la carga de diferentes tipos de recursos. Asi, script-src habilita a los desarrolladores a especificar que fuentes de scripts pueden ejecutarse en un sitio, font-src regula de que origenes se pueden cargar las fuentes tipograficas y style-src regula de que origenes se puede cargar y aplicar estilos en nuestra pagina.
En el contenido de este articulo estaremos viendo algunas de las directivas mas utilizadas, pero en el siguiente enlace tienes una lista de todas las que puedes utilizar y sus descripciones: Directivas CSP.
Directivas mas utilizadas
- default-src: Define los origenes predeterminados para cargar recursos. Si no se especifica una directiva para un tipo de recurso especifico, esta actua como la configuracion por defecto.
- Ejemplo:
default-src 'self';
- Ejemplo:
- script-src: Especifica los origenes validos para los scripts. Esta directiva ayuda a prevenir ataques de inyeccion de scripts.
- Ejemplo:
script-src 'self' https://apis.google.com;
- Ejemplo:
- style-src: Controla los origenes de los cuales se pueden cargar hojas de estilo. Ayuda a evitar la inyeccion de CSS no deseado.
- Ejemplo:
style-src 'self' 'unsafe-inline';
- Ejemplo:
- img-src: Define los origenes de donde se pueden cargar imagenes. Se utiliza para evitar la carga de imagenes de sitios no autorizados.
- Ejemplo:
img-src 'self' https://images.example.com;
- Ejemplo:
- connect-src: Limita los origenes a los cuales el sitio puede conectarse mediante solicitudes AJAX, WebSockets y otras.
- Ejemplo:
connect-src 'self' https://api.example.com;
- Ejemplo:
- font-src: Especifica los origenes 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;
- Ejemplo:
- object-src: Determina los origenes de los cuales se pueden cargar plugins, como
<object>,<embed>o<applet>.- Ejemplo:
object-src 'none';
- Ejemplo:
- media-src: Define los origenes de los cuales se pueden cargar medios de audio y video.
- Ejemplo:
media-src 'self';
- Ejemplo:
- frame-src: Especifica los origenes que pueden ser embebidos como frames. Es util para controlar el contenido de terceros que se incrusta en el sitio.
- Ejemplo:
frame-src https://example.com;
- Ejemplo:
- report-uri / report-to: Especifica donde enviar los informes de violaciones de la politica CSP. Aunque
report-uriesta obsoleto en favor dereport-to, aun es ampliamente soportado.- Ejemplo:
report-uri /csp-violation-report-endpoint/;
- Ejemplo:
Que es CSP Nonce o CSP Estricto?
Un CSP Nonce ("number used once") es un mecanismo de seguridad que permite a los desarrolladores especificar listas blancas de fuentes de contenido legitimo, previniendo asi ataques de tipo Cross-Site Scripting (XSS). Un nonce es un identificador unico que se genera para cada solicitud al servidor. Este identificador se incluye en la politica 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 seran ejecutados o aplicados, bloqueando cualquier elemento malicioso inyectado.
CSP Estricto
El CSP Estricto, o CSP en modo estricto, refiere a la aplicacion de politicas de seguridad de contenido con reglas mas rigurosas, minimizando las posibilidades de ataques XSS. Esto se logra mediante la restriccion de ciertas practicas 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 aplicacion web, haciendo mucho mas dificil para los atacantes explotar vulnerabilidades XSS.
Utilizando CSP Nonce
Para utilizar un nonce con CSP, primero debes generar un nonce unico 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 tambien se agrega a los elementos relevantes en tu HTML.
Header CSP:
Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'
HTML:
<script nonce=\"EDNnf03nceIOfn39fn3e9h3sdfa\">
// Tu codigo JavaScript aqui
</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 sera 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 dinamicamente, generando un nuevo nonce para cada respuesta HTTP. Esto es especialmente util en aplicaciones web que generan contenido dinamico.
- Facilidad de implementacion: Implementar nonces puede ser mas 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 pagina.
Desventajas:
- Mantenimiento: Puede ser mas dificil 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, podria 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 ejecutara, lo que reduce el riesgo de ataques XSS mediante la inyeccion de scripts maliciosos.
- Consistencia: Los hashes proporcionan un metodo consistente para validar contenido, ideal para aplicaciones que sirven contenido estatico 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 generacion de un nuevo hash y la actualizacion del encabezado CSP. Esto puede ser engorroso para el contenido que cambia con frecuencia.
- Complejidad en la gestion: 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, sin importar el tipo de servidor que este corriendo tu aplicacion la implementacion debe ser bastante similar.
Ejemplo agregando CSP con servidor Nginx
Para configurar CSP en Nginx, necesitas agregar la directiva add_header en tu archivo de configuracion de Nginx (nginx.conf o en el archivo de configuracion especifico 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 politica CSP que permite cargar recursos solo desde el mismo origen ('self') y scripts desde el mismo origen asi como desde https://apis.google.com.
Ejemplo agregando CSP con servidor Node.js (Express.js)
Para aplicar CSP en una aplicacion 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 aplicacion:
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 funcion 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>Pagina 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 configurados tus CSP no afecten 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 de verificar si la configuracion CSP aplicada a tu sitio web no esta provocando 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 este enviando el CSP esperado.
Ademas, estas herramientas te mostraran advertencias y errores si algun recurso esta bloqueado por tus politicas CSP, facilitando la identificacion de problemas.
Ejemplo de error de CSP en consola:
2. CSP Evaluator
CSP Evaluator es una herramienta en linea creada por Google que te permite evaluar la seguridad de tus politicas CSP. Solo necesitas ingresar tu politica CSP, y la herramienta te proporcionara un analisis detallado, senalando posibles problemas de seguridad y recomendaciones para mejorar tu CSP.
3. Extensiones del navegador
Existen varias extensiones de navegador disenadas especificamente para trabajar con CSP, como CSP Tester para Google Chrome. Estas extensiones te permiten experimentar con diferentes politicas CSP directamente desde tu navegador, facilitando la identificacion de problemas y la optimizacion de tu configuracion.
4. Mozilla Observatory
Mozilla Observatory es una herramienta en linea que analiza la seguridad de tu sitio web, incluyendo la evaluacion de tu CSP. Proporciona puntuaciones basadas en varias metricas de seguridad y ofrece sugerencias para mejorar la configuracion de seguridad de tu sitio.
Conclusion
En este articulo hemos abordado como los CSP nos permiten mejorar la seguridad de nuestro sitio web restringiendo el contenido que cargamos y limitando las posibilidades de que un atacante pueda insertar codigo malicioso en nuestra pagina web.
Tambien podemos observar en cuales casos es conveniente agregar una capa de seguridad utilizando 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 recalcar que debemos validar nuestras configuraciones CSP. Si bien es cierto que nuestro sitio debe ser seguro, debemos tener cuidado de no afectar la funcionalidad basica del mismo agregando politicas muy restrictivas que puedan crear errores en produccion.
Espero que les haya gustado el contenido del articulo.


