Skip to content

Latest commit

 

History

History
302 lines (214 loc) · 11.6 KB

File metadata and controls

302 lines (214 loc) · 11.6 KB

Content Security Policy (CSP) Configuration

Este documento describe cómo configurar Content Security Policy (CSP) para proteger la aplicación contra ataques XSS y de inyección de datos.

¿Qué es CSP?

Content Security Policy (CSP) es una capa adicional de seguridad que ayuda a detectar y mitigar ciertos tipos de ataques, incluyendo Cross Site Scripting (XSS) y ataques de inyección de datos. CSP proporciona un conjunto de headers HTTP estándar que permiten declarar fuentes aprobadas de contenido que los navegadores deben permitir cargar en la página.

Configuración Actual

Desarrollo

La aplicación ya está configurada con CSP para desarrollo:

  • Vite Dev Server: Los headers CSP se configuran automáticamente en vite.config.ts
  • Meta Tags: Se incluyen meta tags CSP en index.html como respaldo

Política CSP Implementada

La política CSP actual permite:

  • Scripts: Mismo origen, inline scripts, eval (necesario para Vue en desarrollo), y blob URLs
  • Estilos: Mismo origen e inline styles (necesario para Tailwind CSS)
  • Imágenes: Mismo origen, data URLs, blob URLs, y HTTPS
  • Fuentes: Mismo origen y data URLs
  • Conexiones: Mismo origen, API backend, Microsoft OAuth endpoints, y blob URLs
  • Media: Mismo origen, blob URLs, y data URLs
  • Objetos: Ninguno (bloqueado)
  • Base URI: Solo mismo origen
  • Form Actions: Mismo origen, API backend, y Microsoft OAuth endpoints
  • Frame Ancestors: Ninguno (previene clickjacking)
  • Upgrade Insecure Requests: Fuerza HTTPS
  • Block Mixed Content: Bloquea contenido mixto

Protección contra ClickJacking

La aplicación está protegida contra ataques ClickJacking mediante dos mecanismos complementarios:

  1. X-Frame-Options: DENY - Header HTTP que previene que la página sea embebida en frames/iframes
  2. Content-Security-Policy: frame-ancestors 'none' - Directiva CSP moderna que también previene el embedding

Configuración Actual

  • Desarrollo: Headers configurados en vite.config.ts (líneas 86, 97)
  • HTML: Meta tags en index.html como respaldo (línea 14)
  • CSP: frame-ancestors 'none' incluido en la política CSP

Opciones de X-Frame-Options

  • DENY: La página nunca puede ser mostrada en un frame (recomendado para máxima seguridad)
  • SAMEORIGIN: La página solo puede ser mostrada en un frame del mismo origen
  • ALLOW-FROM uri: Permite mostrar la página en un frame desde un origen específico (deprecated)

Nota: La aplicación usa DENY para máxima protección. Si necesitas permitir embedding desde tu mismo dominio, cambia a SAMEORIGIN.

Configuración en Producción

Importante

Los headers HTTP tienen prioridad sobre los meta tags. En producción, debes configurar los headers CSP y X-Frame-Options en tu servidor web (nginx, Apache, etc.) en lugar de depender solo de los meta tags.

⚠️ Protección contra ClickJacking en Producción

CRÍTICO: Asegúrate de que tu servidor web en producción incluya ambos headers:

  1. X-Frame-Options: DENY (o SAMEORIGIN si necesitas embedding del mismo origen)
  2. Content-Security-Policy: ... frame-ancestors 'none' ... (o frame-ancestors 'self' si necesitas embedding del mismo origen)

Sin estos headers en producción, la aplicación será vulnerable a ataques ClickJacking.

Nginx

Agrega los siguientes headers en tu configuración de Nginx:

server {
    listen 443 ssl http2;
    server_name tu-dominio.com;

    # ... otras configuraciones SSL ...

    # Content Security Policy
    # Ajusta las URLs según tu configuración
    set $api_url "https://api.tu-dominio.com";

    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob:; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https:; font-src 'self' data:; connect-src 'self' $api_url https://login.microsoftonline.com https://login.live.com https://graph.microsoft.com blob:; media-src 'self' blob: data:; object-src 'none'; base-uri 'self'; form-action 'self' $api_url https://login.microsoftonline.com https://login.live.com; frame-ancestors 'none'; upgrade-insecure-requests; block-all-mixed-content" always;

    # Headers de seguridad - IMPORTANTE: X-Frame-Options previene ClickJacking
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "DENY" always;  # Protección contra ClickJacking
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;

    # ... resto de la configuración ...

    location / {
        root /var/www/securis-web/dist;
        try_files $uri $uri/ /index.html;
    }
}

Apache

Agrega los siguientes headers en tu configuración de Apache (.htaccess o configuración del servidor):

<IfModule mod_headers.c>
    # Content Security Policy
    # Ajusta las URLs según tu configuración
    Header set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob:; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https:; font-src 'self' data:; connect-src 'self' https://api.tu-dominio.com https://login.microsoftonline.com https://login.live.com https://graph.microsoft.com blob:; media-src 'self' blob: data:; object-src 'none'; base-uri 'self'; form-action 'self' https://api.tu-dominio.com https://login.microsoftonline.com https://login.live.com; frame-ancestors 'none'; upgrade-insecure-requests; block-all-mixed-content"

    # Headers de seguridad - IMPORTANTE: X-Frame-Options previene ClickJacking
    Header set X-Content-Type-Options "nosniff"
    Header set X-Frame-Options "DENY"  # Protección contra ClickJacking
    Header set X-XSS-Protection "1; mode=block"
    Header set Referrer-Policy "strict-origin-when-cross-origin"
    Header set Permissions-Policy "geolocation=(), microphone=(), camera=()"
</IfModule>

Node.js / Express

Si estás usando Express para servir la aplicación:

const express = require("express");
const app = express();

// Content Security Policy
const apiUrl = process.env.API_URL || "https://api.tu-dominio.com";
const cspPolicy = [
	"default-src 'self'",
	"script-src 'self' 'unsafe-inline' 'unsafe-eval' blob:",
	"style-src 'self' 'unsafe-inline'",
	"img-src 'self' data: blob: https:",
	"font-src 'self' data:",
	`connect-src 'self' ${apiUrl} https://login.microsoftonline.com https://login.live.com https://graph.microsoft.com blob:`,
	"media-src 'self' blob: data:",
	"object-src 'none'",
	"base-uri 'self'",
	`form-action 'self' ${apiUrl} https://login.microsoftonline.com https://login.live.com`,
	"frame-ancestors 'none'",
	"upgrade-insecure-requests",
	"block-all-mixed-content",
].join("; ");

app.use((req, res, next) => {
	res.setHeader("Content-Security-Policy", cspPolicy);
	res.setHeader("X-Content-Type-Options", "nosniff");
	res.setHeader("X-Frame-Options", "DENY"); // Protección contra ClickJacking
	res.setHeader("X-XSS-Protection", "1; mode=block");
	res.setHeader("Referrer-Policy", "strict-origin-when-cross-origin");
	res.setHeader(
		"Permissions-Policy",
		"geolocation=(), microphone=(), camera=()"
	);
	next();
});

// Servir archivos estáticos
app.use(express.static("dist"));

Optimización para Producción

Consideraciones de Seguridad

  1. 'unsafe-inline' y 'unsafe-eval':

    • En desarrollo, estos son necesarios para Vue y algunas librerías
    • En producción, considera usar nonces para scripts y estilos inline
    • Vue 3 en modo producción no debería necesitar 'unsafe-eval'
  2. Nonces:

    • Para mayor seguridad, implementa nonces para scripts y estilos inline
    • Requiere configuración del servidor para generar nonces únicos por request
  3. Reporting:

    • Considera agregar report-uri o report-to para recibir reportes de violaciones CSP
    • Útil para detectar y corregir problemas en producción

Ejemplo con Nonces (Nginx)

# Generar nonce único por request
set $nonce $request_id;

# Usar nonce en CSP
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-$nonce' blob:; style-src 'self' 'nonce-$nonce'; ..." always;

Luego, en tu HTML, usa el nonce:

<script nonce="{{ $nonce }}">
	// Tu código
</script>

Verificación

Herramientas de Verificación

  1. Browser DevTools:

    • Abre las DevTools (F12)
    • Ve a la pestaña "Console"
    • Busca violaciones CSP (aparecerán como errores)
  2. Online CSP Evaluator:

    • Usa herramientas como CSP Evaluator
    • Ingresa tu política CSP para validarla
  3. Headers HTTP:

    • Usa herramientas como curl o extensiones del navegador
    • Verifica que los headers CSP estén presentes:
    curl -I https://tu-dominio.com

Troubleshooting

Problemas Comunes

  1. Errores de CSP en la consola:

    • Revisa qué recursos están siendo bloqueados
    • Ajusta la política CSP para permitir esos recursos si son legítimos
    • Verifica que las URLs estén correctamente configuradas
  2. Microsoft OAuth no funciona:

    • Asegúrate de que https://login.microsoftonline.com y https://login.live.com estén en connect-src
    • Verifica que form-action incluya estos dominios
  3. PDFs no se cargan:

    • Verifica que blob: esté permitido en connect-src, media-src, e img-src
    • Asegúrate de que data: esté permitido si usas base64
  4. Estilos no se aplican:

    • Verifica que style-src incluya 'unsafe-inline' o usa nonces
    • Tailwind CSS puede necesitar inline styles
  5. Error de ClickJacking detectado:

    • Verifica que X-Frame-Options esté configurado en tu servidor web
    • Verifica que frame-ancestors esté en la política CSP
    • Usa curl -I https://tu-dominio.com para verificar los headers
    • Asegúrate de que los headers se apliquen a todas las rutas, no solo a la raíz
    • En Nginx, usa always después de add_header para asegurar que se aplique incluso en errores

Verificación de Protección contra ClickJacking

Verificar Headers

# Verificar que los headers estén presentes
curl -I https://tu-dominio.com

# Debes ver:
# X-Frame-Options: DENY
# Content-Security-Policy: ... frame-ancestors 'none' ...

Herramientas de Prueba

  1. Browser DevTools:

    • Abre las DevTools (F12)
    • Ve a la pestaña "Network"
    • Recarga la página
    • Haz clic en cualquier request
    • Verifica los headers de respuesta
  2. Online Security Headers Checker:

    • Usa herramientas como SecurityHeaders.com
    • Ingresa tu URL para verificar todos los headers de seguridad
  3. Prueba Manual:

    <!-- Intenta embebar tu página en un iframe - debería fallar -->
    <iframe src="https://tu-dominio.com"></iframe>

Recursos Adicionales