CSRF (Cross-Site Request Forgery): Prevención y Defensa
Aprende qué es CSRF, cómo funcionan los ataques de falsificación de solicitudes entre sitios y cómo proteger tus aplicaciones usando tokens, cookies SameSite y verificación de origen.
TL;DR - Resumen rápido
- CSRF explota que los navegadores envían automáticamente cookies con cada solicitud al dominio
- Los tokens CSRF únicos por sesión son la defensa principal: el atacante no puede conocerlos
- SameSite=Lax bloquea cookies en POST cross-site manteniendo buena experiencia de usuario
- Verifica headers Origin/Referer en el servidor para rechazar solicitudes de dominios desconocidos
- Usa sessionStorage para tokens (no localStorage) y combina múltiples capas de defensa
Introducción a CSRF
Cross-Site Request Forgery (CSRF) es un ataque que engaña a usuarios para que ejecuten acciones no deseadas en sitios web donde están autenticados. A diferencia de XSS, CSRF no requiere inyectar código malicioso; simplemente aprovecha que el navegador envía automáticamente cookies de autenticación con cada solicitud.
Imagina que estás logueado en tu banco y visitas un sitio malicioso. Ese sitio puede enviar una solicitud a tu banco en tu nombre, y tu navegador incluirá automáticamente las cookies de autenticación. Si el banco no tiene protecciones CSRF, la solicitud se procesará como si tú la hubieras iniciado.
CSRF vs XSS
Mientras que XSS inyecta código que se ejecuta en el navegador de la víctima, CSRF engaña al navegador para que envíe solicitudes que parecen legítimas. XSS requiere ejecutar código, CSRF solo requiere que el usuario haga clic en un enlace o visite una página maliciosa.
Cómo Funciona CSRF
CSRF funciona aprovechando cómo los navegadores manejan las cookies y las solicitudes HTTP. Cuando un usuario está autenticado en un sitio, el navegador envía las cookies de autenticación con cada solicitud a ese sitio, sin importar de dónde provenga la solicitud.
- <strong>Víctima autenticada</strong>: El usuario inicia sesión en el sitio objetivo (ej: banco.com)
- <strong>Visita sitio malicioso</strong>: La víctima visita evil.com que contiene código malicioso
- <strong>Solicitud cross-site</strong>: evil.com envía una solicitud POST a banco.com
- <strong>Cookies automáticas</strong>: El navegador envía automáticamente las cookies de autenticación
- <strong>Acción ejecutada</strong>: El sitio objetivo procesa la solicitud como legítima
Ejemplo de Ataque CSRF
Este ejemplo muestra cómo un atacante podría crear una página maliciosa que transfiere dinero de la cuenta de una víctima sin su conocimiento.
El formulario oculto se envía automáticamente con JavaScript al cargar la página. Como la víctima está autenticada en banco.com, el navegador incluye sus cookies de sesión con la solicitud. El banco ve una petición POST válida con credenciales correctas y procesa la transferencia. La víctima nunca ve el formulario ni sospecha que algo sucedió.
Ataques Silenciosos
Los ataques CSRF pueden ser completamente invisibles para la víctima. El formulario puede estar oculto con CSS, o el ataque puede ejecutarse en un iframe invisible. Por eso es crucial implementar defensas automáticas que no dependan de la interacción del usuario.
Prevención de CSRF
La prevención de CSRF requiere múltiples capas de defensa. No existe una sola solución mágica; debes combinar tokens CSRF, cookies SameSite y verificación de origen para proteger tu aplicación.
- <strong>Tokens CSRF</strong>: Tokens únicos por sesión que se validan en cada solicitud POST
- <strong>Cookies SameSite</strong>: Configuración que previene envío de cookies en solicitudes cross-site
- <strong>Verificación de origen</strong>: Valida headers Origin y Referer para asegurar el origen
- <strong>Double Submit Cookie</strong>: Envía el token tanto en cookie como en parámetro
- <strong>Custom Headers</strong>: Usa headers personalizados que no pueden enviarse cross-site
Tokens CSRF
Los tokens CSRF son la defensa principal contra estos ataques. Son strings aleatorios y únicos que el servidor genera para cada sesión y que deben incluirse en cada solicitud que modifica estado.
El código genera un token usando crypto.getRandomValues() que produce bytes criptográficamente seguros. El token se almacena en sessionStorage y se agrega como campo oculto en formularios o como header X-CSRF-Token en peticiones fetch. Los atacantes no pueden obtener este token porque está aislado al dominio legítimo y no se envía cross-site.
Tokens por Sesión
Los tokens CSRF deben ser únicos por sesión, no por solicitud. Un token por sesión es suficiente y más fácil de implementar. Solo debes regenerar el token cuando el usuario inicia sesión nuevamente o después de un período de tiempo prolongado.
Verificación de Origen
Verificar el origen de las solicitudes usando los headers Origin y Referer es una capa adicional de defensa. Los navegadores envían automáticamente estos headers para indicar de dónde proviene la solicitud.
Los navegadores envían el header Origin en solicitudes POST, PUT y DELETE, yReferer en la mayoría de solicitudes. El servidor valida que estos headers apuntan al dominio correcto (ej: mi-sitio.com). Si la solicitud viene de evil.com, el servidor rechaza la petición con HTTP 403. Esta verificación debe ser en el servidor porque los headers del cliente pueden ser manipulados.
Verificación en Servidor
Nunca confíes únicamente en la verificación de origen en el cliente. Los atacantes pueden falsificar estos headers o usar técnicas para evadirlos. La verificación debe implementarse en el servidor como parte de la lógica de autenticación y autorización.
Errores Comunes
Estos son los errores más frecuentes al implementar defensas contra CSRF y cómo evitarlos.
Los errores más graves son: usar tokens predecibles (como token-123), solo validar en el cliente donde los atacantes pueden saltarse la validación, guardar tokens en localStorage que son accesibles por scripts XSS, y no configurar SameSite en cookies de sesión. Cada error por sí solo puede comprometer completamente la seguridad CSRF.
Defensa en Profundidad
No confíes en una sola defensa. Combina tokens CSRF, cookies SameSite y verificación de origen. Si una capa falla, las otras pueden proteger tu aplicación. La seguridad es un proceso continuo, no una configuración única.
Resumen: Prevención de CSRF
Conceptos principales:
- •CSRF explota el envío automático de cookies del navegador a cualquier solicitud
- •Los atacantes no necesitan robar cookies, solo engañar al navegador para enviarlas
- •Los ataques son silenciosos: formularios ocultos, iframes invisibles, o fetch en segundo plano
- •Tokens CSRF funcionan porque el atacante no puede acceder al DOM del sitio legítimo
- •SameSite=Lax previene CSRF en POST pero permite navegación normal en enlaces GET
Mejores prácticas:
- •Genera tokens con crypto.getRandomValues() y almacena en sessionStorage
- •Valida tokens en el servidor (no solo cliente) antes de procesar acciones
- •Configura cookies con SameSite=Lax, Secure y HttpOnly
- •Verifica Origin/Referer en servidor para rechazar solicitudes externas
- •Combina todas las defensas: tokens + SameSite + verificación de origen