Command Palette

Search for a command to run...

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.

Lectura: 12 min
Nivel: Intermedio

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.

csrf-ataque-malicioso.html
Loading code...

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.

implementacion-token-csrf.js
Loading code...

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.

Cookies SameSite

La propiedad SameSite de las cookies es una defensa moderna y efectiva contra CSRF. Controla cuándo las cookies se envían con solicitudes cross-site.

cookies-samesite.js
Loading code...

SameSite=Lax permite que las cookies se envíen cuando el usuario hace clic en un enlace desde otro sitio (navegación GET de nivel superior), pero bloquea cookies en formularios POST cross-site y peticiones fetch. Esto previene CSRF manteniendo buena experiencia de usuario. SameSite=Strictbloquea todas las cookies cross-site, incluso en enlaces, lo que puede romper flujos legítimos de login.

SameSite Strict vs Lax

SameSite=Strict bloquea todas las cookies cross-site, incluso cuando el usuario navega haciendo clic en enlaces. Esto puede romper la experiencia de usuario. SameSite=Lax es más pragmático: permite navegaciones pero bloquea ataques CSRF que usan formularios o fetch.

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.

verificacion-origen.js
Loading code...

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.

errores-comunes-csrf.js
Loading code...

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