Cross-site request forgery es una de esas vulnerabilidades que parecen simples hasta que intentas explotarlas en una aplicación moderna. En teoría: engañar al navegador de una víctima para que realice una solicitud autenticada hacia un sitio objetivo. En la práctica: la validación de tokens CSRF, las políticas de cookies SameSite y las verificaciones de Referer lo han hecho significativamente más difícil, pero no imposible.

En 2026, el CSRF puro es menos común en plataformas grandes, pero sigue apareciendo con regularidad en herramientas internas, aplicaciones empresariales heredadas, APIs construidas a medida y cualquier aplicación que implemente la protección CSRF de forma descuidada. Y cuando los tokens CSRF están presentes pero mal configurados, el bypass suele ser trivialmente sencillo.

Esta guía cubre cómo funciona CSRF mecánicamente, cómo encontrarlo y confirmarlo, técnicas de explotación, métodos comunes de bypass y cómo encadenar CSRF con otras vulnerabilidades para lograr impacto real.


¿Qué es CSRF?

Cross-site request forgery (CSRF) explota la inclusión automática de credenciales por parte del navegador —cookies, cabeceras de autenticación HTTP— en cada solicitud hacia un dominio. Si una víctima está autenticada en un sitio objetivo y visita una página controlada por el atacante, esa página puede hacer que el navegador de la víctima envíe solicitudes al sitio objetivo con las credenciales de sesión de la víctima adjuntas.

El servidor ve una solicitud autenticada. No puede distinguir si el usuario la realizó intencionalmente.

Ejemplo clásico:

  1. El usuario inicia sesión en banco.com — se establece la cookie de sesión
  2. El usuario visita la página del atacante en evil.com
  3. evil.com contiene <img src="https://banco.com/transferir?destino=atacante&monto=10000">
  4. El navegador accede a esa URL — con la cookie de sesión incluida
  5. El banco procesa la transferencia como el usuario autenticado

El ataque funciona porque:

  • Las cookies se envían automáticamente con cada solicitud al dominio de la cookie
  • El servidor no puede distinguir una solicitud intencional de una falsificada por una página de terceros
  • El atacante no necesita leer la respuesta — para operaciones que cambian estado, enviar la solicitud es suficiente

Cómo CSRF Difiere de XSS

Confusión común: CSRF y XSS ambos involucran comportamiento malicioso del navegador, pero el mecanismo y la perspectiva del defensor son diferentes.

PropiedadXSSCSRF
El atacante inyectaCódigo en el sitio objetivoSolicitudes desde el navegador de la víctima
Se ejecuta enNavegador de la víctima, origen del sitio objetivoNavegador de la víctima, origen de terceros
Lee la respuestaSí (mismo origen)No (cross-origin, bloqueado por SOP)
Requiere autenticación del usuarioNoSí (usa la sesión de la víctima)
Enfoque de bypassCSP, codificación de salidaTokens CSRF, SameSite, Referer

CSRF no permite robar datos — no puedes leer la respuesta cross-origin. Permite realizar acciones como la víctima.


Impacto

¿Qué se puede hacer con CSRF? Cualquier cosa que la víctima pueda hacer, sin acceso de lectura:

  • Toma de cuenta — cambiar email, cambiar contraseña, agregar aplicación OAuth controlada por el atacante
  • Escalada de privilegios — agregar cuentas de administrador, modificar roles de usuario
  • Transacciones financieras — transferencias, compras, cambios de suscripción
  • Eliminación de datos — borrar archivos, cuentas, configuraciones
  • Recolección de credenciales — combinado con XSS almacenado, CSRF se vuelve prácticamente ilimitado

El impacto real depende de lo que haga el endpoint vulnerable. Un CSRF contra un endpoint de cambio de contraseña que no requiere la contraseña actual equivale a una toma de cuenta completa.


Condiciones para CSRF

Deben cumplirse tres condiciones para que un ataque CSRF tenga éxito:

  1. Una acción relevante — algo que cambia estado en el servidor (cambiar email, transferir fondos, modificar configuraciones)
  2. Manejo de sesión basado en cookies — la aplicación usa cookies para identificar usuarios autenticados (no cabeceras personalizadas como X-Auth-Token que no pueden falsificarse cross-origin)
  3. Sin parámetros impredecibles — sin token CSRF, o un token que puede ser bypasseado

Cuando se cumplen las tres, CSRF es explotable.


Detección con Burp Suite

Detección Pasiva

El Scanner de Burp Suite Professional detecta automáticamente problemas potenciales de CSRF. En Burp Suite Community, los identificas manualmente.

Qué buscar en las solicitudes:

  • Solicitudes POST, PUT, DELETE que cambian estado del servidor
  • Ausencia de tokens CSRF
  • Tokens presentes en cookies pero no en el cuerpo de la solicitud (no ayuda — las cookies se envían automáticamente de todas formas)
  • Tokens predecibles o estáticos

Paso 1 — Interceptar solicitudes que cambian estado:

Navega por la aplicación autenticado, realizando todas las acciones principales: cambiar email, cambiar contraseña, actualizar perfil, eliminar elementos, enviar mensajes. Captura estas solicitudes en Burp Proxy.

Paso 2 — Examinar cada solicitud en busca de protecciones CSRF:

Para cada solicitud POST que cambia estado, verifica:

  • ¿Hay un csrf_token, _token, nonce o parámetro similar?
  • ¿Se valida ese parámetro del lado del servidor?
  • ¿Se verifica la cabecera Origin o Referer?
  • ¿Hay un atributo SameSite en la cookie de sesión?

Paso 3 — Probar la validación del token:

Si existe un token, pruébalo:

1. Elimina el token completamente → ¿la solicitud tiene éxito?
2. Envía un valor de token vacío → ¿la solicitud tiene éxito?
3. Usa un token de otra sesión → ¿la solicitud tiene éxito?
4. Modifica un carácter del token → ¿la solicitud tiene éxito?

Si alguno de estos tiene éxito, la protección CSRF está rota.

Usando el Generador de PoC CSRF de Burp

Burp Suite Pro tiene un generador de PoC CSRF integrado:

  1. Haz clic derecho en cualquier solicitud en el historial de Burp Proxy
  2. Selecciona Engagement tools → Generate CSRF PoC
  3. Burp genera una página HTML que enviará esa solicitud
  4. Haz clic en Test in browser para activarla desde tu navegador

Esta es la forma más rápida de confirmar explotabilidad.

PoC manual (edición Community):

Para una solicitud POST, la estructura básica del PoC:

<html>
  <body>
    <form action="https://objetivo.com/cambiar-email" method="POST">
      <input type="hidden" name="email" value="[email protected]" />
    </form>
    <script>document.forms[0].submit();</script>
  </body>
</html>

Para cambios de estado basados en GET:

<img src="https://objetivo.com/eliminar-cuenta?confirmar=true" />

Técnicas de Bypass de Token CSRF

Las aplicaciones modernas generalmente implementan tokens CSRF. Aquí está cómo suelen estar mal implementados.

1. Token No Validado

El hallazgo más común: el token está presente en la solicitud pero el servidor no lo verifica realmente.

Prueba: Elimina el parámetro del token completamente y reenvía. Si la solicitud tiene éxito, no se está realizando validación.

Algunas implementaciones vinculan el token a la sesión pero lo validan contra una cookie separada en lugar del estado de sesión del lado del servidor. Si tanto la cookie como el parámetro coinciden, la solicitud es aceptada — incluso si ambos fueron falsificados.

Ataque (bypass del patrón Double Submit Cookie):

Si puedes establecer una cookie en el navegador de la víctima (por ejemplo, mediante XSS en un subdominio, document.cookie desde un dominio relacionado, o cookie tossing):

  1. Establece csrf_cookie=valor_falsificado en el navegador de la víctima
  2. Envía la solicitud con csrf_token=valor_falsificado en el cuerpo
  3. El servidor verifica cookie vs parámetro — coinciden, solicitud aceptada

Esto funciona cuando el servidor no mantiene estado de sesión del lado del servidor para el token.

3. Token No Vinculado a la Sesión del Usuario

Algunas implementaciones generan tokens globalmente válidos — no vinculados a la sesión de un usuario específico.

Prueba: Inicia sesión como usuario A, captura el token CSRF. Inicia sesión como usuario B. Intenta usar el token del usuario A en la solicitud del usuario B. Si funciona, los tokens son globales.

4. Token Presente Pero Predecible

Si el token CSRF se genera a partir de:

  • Timestamp + ID de usuario (con XOR o Base64)
  • Enteros secuenciales
  • Valor estático embebido en HTML

…puede ser predecible o calculable. Analiza la entropía del token. Un token débil puede adivinarse o forzarse por fuerza bruta.

5. Bypass de Cabecera Referer

Algunas aplicaciones validan la cabecera Referer en lugar de un token. La validación de Referer puede bypassearse:

Referer nulo:

<meta name="referrer" content="no-referrer">
<form action="https://objetivo.com/cambiar-email" method="POST">
  ...
</form>

El navegador omite la cabecera Referer. Si el servidor acepta solicitudes sin Referer (tratando la ausencia como confiable), es explotable.

Coincidencia de subdominio en Referer:

Si el servidor hace coincidencia de prefijo/sufijo en Referer:

# Si el servidor verifica: referer.startsWith("https://objetivo.com")
# Aloja tu PoC en: https://objetivo.com.atacante.com/csrf.html

# Si el servidor verifica: referer.endsWith("objetivo.com")
# Aloja en: https://atacanteobjetivo.com/csrf.html

SameSite es ahora la defensa principal contra CSRF en la mayoría de las aplicaciones modernas. Entender qué significa cada valor y cómo bypassearlo es fundamental.

Valor SameSiteComportamientoRiesgo CSRF
StrictCookie nunca enviada cross-siteCasi inmune
LaxCookie enviada en navegaciones de nivel superior (GET)Protección parcial
NoneCookie siempre enviada (requiere Secure)Sin protección
(No establecido, Chrome 80+)Lax por defectoProtección parcial

Bypass de Lax — Navegación GET de nivel superior:

SameSite=Lax bloquea cookies en solicitudes POST cross-site pero las permite en navegaciones GET de nivel superior. Si la acción vulnerable está en un endpoint GET:

<!-- Abre la URL objetivo como navegación de nivel superior — cookie incluida con Lax -->
<script>
  window.location = "https://objetivo.com/eliminar-cuenta?confirmar=true";
</script>

Bypass de Lax — Anulación de restricciones de método:

Algunos frameworks aceptan solicitudes POST como GET cuando está presente el parámetro _method=POST (anulación de método). Si el endpoint vulnerable puede activarse via GET con anulación de método, las cookies Lax se envían.

Bypass de SameSite=Strict mediante cadena:

Un sitio que usa Strict SameSite tiene fuerte protección contra CSRF directo. Sin embargo:

  1. Si el sitio tiene un redirect abierto, puedes encadenar: la víctima visita tu página → redirect a objetivo.com/redirect?url=objetivo.com/accion-csrf → la cookie Strict ahora se incluye porque el navegador ahora está en el mismo sitio
  2. Si hay XSS en el dominio objetivo, todas las protecciones CSRF son irrelevantes — XSS da ejecución de código en el mismo origen

None + Secure sigue siendo explotable:

Si la cookie de sesión es SameSite=None; Secure, CSRF es completamente explotable desde cualquier página cross-site. Esta configuración era común en implementaciones antiguas y todavía aparece en aplicaciones heredadas.


Explotación — Construyendo Payloads Reales

Envío Básico de Formulario

La página PoC envía automáticamente un formulario:

<html>
  <body onload="document.getElementById('form').submit()">
    <form id="form" action="https://objetivo.com/api/cambiar-email" method="POST">
      <input type="hidden" name="email" value="[email protected]" />
      <input type="hidden" name="confirmar" value="[email protected]" />
    </form>
  </body>
</html>

Ocultando el PoC en un iframe invisible:

<iframe style="display:none" name="frame-oculto"></iframe>
<form target="frame-oculto" action="https://objetivo.com/cambiar-password" method="POST">
  <input type="hidden" name="password" value="Hackeado123!" />
  <input type="hidden" name="confirmar" value="Hackeado123!" />
</form>
<script>document.forms[0].submit();</script>

El formulario se envía al iframe oculto — sin navegación de página visible.

Cuerpos de Solicitud JSON

Algunas APIs solo aceptan Content-Type: application/json. Los formularios solo pueden enviar application/x-www-form-urlencoded, multipart/form-data o text/plain. Esto parece bloquear CSRF — pero verifica cuidadosamente:

¿La API realmente aplica Content-Type?

Prueba enviando el payload JSON con Content-Type: text/plain:

<form action="https://objetivo.com/api/actualizar" method="POST" enctype="text/plain">
  <input type="hidden" name='{"email":"[email protected]","x":"' value='"}' />
</form>

Esto envía el cuerpo: {"email":"[email protected]","x":""} con Content-Type text/plain. Si el servidor lo parsea de todas formas (muchos lo hacen), es explotable.

Fetch con modo no-cors:

fetch("https://objetivo.com/api/cambiar-email", {
  method: "POST",
  mode: "no-cors",
  credentials: "include",
  headers: {"Content-Type": "application/x-www-form-urlencoded"},
  body: "email=atacante%40evil.com"
});

El modo no-cors restringe qué cabeceras se pueden establecer pero permite tipos de contenido simples. Las credenciales se incluyen.

Solicitudes Multipart

Si el endpoint requiere multipart/form-data:

<form action="https://objetivo.com/actualizar-perfil" method="POST" enctype="multipart/form-data">
  <input type="hidden" name="email" value="[email protected]" />
</form>

Multipart es un tipo de contenido simple — se envía automáticamente cross-origin sin preflight.


Cadena CSRF + XSS

CSRF tiene impacto limitado como ataque independiente porque no puedes leer respuestas. Encadenar CSRF con XSS elimina esa restricción por completo.

XSS Almacenado → Robar Token CSRF → Enviar Solicitud Autenticada:

Si la aplicación tiene XSS almacenado:

// Payload inyectado via XSS almacenado
var token = document.querySelector('[name="csrf_token"]').value;
fetch("https://objetivo.com/cambiar-email", {
  method: "POST",
  credentials: "include",
  headers: {"Content-Type": "application/x-www-form-urlencoded"},
  body: "[email protected]&csrf_token=" + token
});

XSS se ejecuta en el mismo origen — puedes leer el token CSRF del DOM y enviarlo. Las protecciones CSRF se vuelven irrelevantes una vez que hay XSS presente.

Cadena CSRF → Toma de Cuenta:

La cadena CSRF más impactante:

  1. CSRF de cambio de email (sin requerir contraseña actual) → el email de la víctima cambia a [email protected]
  2. Restablecimiento de contraseña via email controlado por el atacante
  3. Toma de cuenta completa — sin necesidad de robar tokens

Si el cambio de email no requiere contraseña y la recuperación de cuenta es por email, un solo CSRF te da la cuenta.


CSRF Contra APIs REST

Las APIs REST modernas a veces se asumen incorrectamente como inmunes a CSRF. Conceptos erróneos comunes:

Error 1: “Usamos JSON, así que estamos seguros”

Como se muestra arriba — si el servidor no valida estrictamente Content-Type, los endpoints JSON son explotables via cuerpos text/plain.

Error 2: “Verificamos la cabecera Origin”

La verificación de la cabecera Origin funciona correctamente cuando se implementa apropiadamente, pero:

  • Si se acepta el Origin nulo (algunos servidores lo whitelistean por razones de compatibilidad), los iframes con el atributo sandbox pueden bypassearlo
  • Si la verificación de origen es una coincidencia de prefijo o está mal anclada, se aplican bypasses similares a los de Referer

Error 3: “Usamos bearer tokens en la cabecera Authorization”

Si la API usa Authorization: Bearer <token> en cabeceras en lugar de cookies, CSRF no aplica — las cabeceras personalizadas no pueden establecerse cross-origin sin preflight, lo cual activaría un preflight CORS que el servidor rechazaría. Esta es la arquitectura correcta para APIs.

El problema: si la misma API también acepta cookies de sesión (para acceso basado en navegador), CSRF aplica a las rutas de autenticación basadas en cookies.


Bypass Avanzado de Validación Referer

Algunas aplicaciones validan Referer con coincidencia de subcadena:

# Vulnerable: verifica si el dominio objetivo aparece en cualquier lugar del referer
if "objetivo.com" in request.headers.get("Referer", ""):
    aceptar()

Ataque de subdominio: Aloja tu PoC en https://objetivo.com.atacante.com/csrf.html. El Referer contendrá objetivo.com.

Ataque de ruta: Aloja en https://atacante.com/objetivo.com/csrf.html. El Referer contiene objetivo.com en la ruta.

Ambos bypasean la coincidencia naive de subcadena.


Flujo de Prueba Práctico

Este es el flujo a usar durante un engagement de pentest de aplicaciones web:

1. Mapear todos los endpoints que cambian estado (POST/PUT/DELETE)
   → Enfocarse en: cambios de cuenta, acciones de admin, operaciones financieras

2. Para cada endpoint:
   a. ¿Hay token CSRF presente?
      No → Generar PoC, probar explotación directa
      Sí → Continuar

   b. Eliminar token → ¿la solicitud tiene éxito?
      Sí → Token no validado

   c. Token vacío → ¿la solicitud tiene éxito?
      Sí → Token verificado por presencia, no por valor

   d. Token de otra sesión → ¿la solicitud tiene éxito?
      Sí → Token no vinculado a sesión

   e. Verificar atributo SameSite en cookie
      None/ausente → CSRF completamente explotable via formulario cross-origin
      Lax → Buscar cambios de estado basados en GET
      Strict → Buscar redirects abiertos o cadenas XSS

   f. Verificar validación de Referer
      Probar Referer nulo (meta tag referrer)
      Probar bypass de subdominio

3. Confirmar explotabilidad:
   → Construir página PoC
   → Probar en navegador mientras se está autenticado en el objetivo
   → Verificar que el cambio de estado ocurrió

Hallazgos CSRF en el Mundo Real

GitHub (2012): CSRF en el flujo de autorización OAuth. El atacante podía vincular la cuenta de GitHub de la víctima a una aplicación OAuth del atacante — vinculación silenciosa de cuenta, acceso completo.

Netflix (2014): CSRF permitía cambiar la dirección de envío para entregas de DVD y agregar títulos de alquiler — sin protección de token en esos endpoints.

YouTube (2008): CSRF permitía agregar videos a listas de reproducción, enviar comentarios y agregar amigos — todo sin interacción del usuario.

Citrix ShareFile (2020): CSRF en endpoint de cambio de contraseña. No se requería contraseña actual, sin token CSRF — toma de cuenta directa.

El patrón: acciones de alto valor y baja fricción (cambio de email/contraseña, vinculación de cuenta) con validación de token ausente o rota.


Mitigaciones (Para Redacción de Informes)

Al redactar hallazgos, incluye las mitigaciones estándar:

Tokens CSRF (Patrón Synchronizer Token):

  • Generar token impredecible de alta entropía por sesión
  • Validar del lado del servidor en cada solicitud que cambie estado
  • El token debe estar vinculado a la sesión, no ser válido globalmente
  • Rotar el token después de acciones sensibles

Cookies SameSite:

  • SameSite=Strict para todas las cookies de sesión donde sea posible
  • SameSite=Lax como mínimo para cookies de sesión no-API
  • Nunca usar SameSite=None sin justificación sólida

Validación de Origin / Referer:

  • Validar la cabecera Origin del lado del servidor para APIs habilitadas con CORS
  • Usar coincidencia estricta, no coincidencia de subcadena
  • Rechazar solicitudes de orígenes inesperados

Cabeceras de Solicitud Personalizadas:

  • Las APIs deben usar Authorization: Bearer en cabeceras, no cookies
  • Las cabeceras personalizadas (p.ej., X-Requested-With: XMLHttpRequest) proporcionan protección CSRF ya que no pueden establecerse cross-origin sin preflight

Double Submit Cookie (con HMAC):

  • Firmar el token con la clave de sesión antes de establecerlo como cookie
  • Validar la firma del lado del servidor — las cookies falsificadas fallarán la verificación de firma

CSRF vs. Clickjacking

A menudo confundidos, a menudo encadenados. Distinción clave:

CSRF: El navegador de la víctima hace una solicitud de forma invisible. El usuario no interactúa con nada visible del sitio objetivo.

Clickjacking: La víctima hace clic en algo visible (el sitio del atacante), pero el clic cae en un iframe transparente sobre el sitio objetivo. La víctima ve un botón falso pero hace clic en uno real del objetivo.

Cuando las acciones requieren interacción del usuario (drag-and-drop, formularios complejos), el clickjacking puede funcionar donde CSRF no. Cuando las acciones pueden activarse via GET/POST simple, CSRF es más sencillo. Se pueden encadenar: clickjacking para realizar una acción que bypasea los requisitos del token CSRF haciendo que el usuario “intencionalmente” envíe el formulario.


Entornos de Práctica

Desarrolla tus habilidades CSRF en entornos legales:

  • DVWA — Módulo CSRF dedicado, múltiples niveles de dificultad
  • WebGoat — Aplicación web defectuosa de OWASP, lecciones de CSRF incluidas
  • Juice Shop — SPA moderno, desafíos de CSRF y seguridad de API
  • HackTheBox / TryHackMe — Periódicamente incluyen CSRF en máquinas de aplicaciones web
  • PortSwigger Web Security Academy — Los mejores labs de CSRF disponibles, gratuitos, cubre todas las técnicas de bypass

Para un entorno de laboratorio completo que controles, un VPS de $6/mes es suficiente para levantar cualquiera de estos:

👉 Vultr — Despliega un VPS de laboratorio — Instancias SSD desde $6/mes. Haz snapshots del estado de tu laboratorio, reconstruye desde cero cuando quieras.

👉 DigitalOcean — Droplets para labs de seguridad — Mismo rango de precio, interfaz limpia, ideal para instancias dedicadas de DVWA/WebGoat.


Guías Relacionadas


¿Necesitas Contenido de Seguridad Profesional?

CipherWrite — artículos de ciberseguridad, documentación técnica e informes de red team escritos por profesionales. Para equipos que necesitan contenido que sea realmente preciso.