Imagina que alguien engaña a un visitante para que haga clic en un enlace mientras tiene abierta la sesión de su banco. Ese enlace lleva a un formulario oculto que, sin que el visitante lo sepa, envía al banco una orden para transferir dinero. El banco ve una petición legítima de un usuario autenticado y la procesa. El atacante ha movido dinero con la cuenta de la víctima sin haber conocido nunca su contraseña.
Eso es el CSRF (Cross-Site Request Forgery, falsificación de petición en sitios cruzados): un ataque en el que un atacante engaña a una víctima para que envíe, sin darse cuenta, un formulario o una petición a otra web en la que ya tiene la sesión iniciada.
Qué aprenderás: qué son los ataques CSRF y cómo funcionan, por qué son tan peligrosos aunque haya otras medidas de seguridad, cómo los evitan los tokens CSRF y cómo proteger tus formularios.
¿Qué es el CSRF?
CSRF (se pronuncia "sea-surf") significa Cross-Site Request Forgery. Es un ataque que aprovecha que, si tienes la sesión iniciada en una web, tu navegador confía automáticamente en ella e incluye tu sesión en cada petición que haces a ese sitio, aunque la petición venga de otra web.
El ataque consiste en engañar a un visitante con la sesión iniciada para que envíe, sin saberlo, un formulario a una web donde tiene cuenta. El atacante no puede ver la contraseña de la víctima. No la necesita. Solo hace falta que la víctima ya tenga la sesión iniciada y que le engañe para que haga una petición (como enviar un formulario oculto) que haga lo que el atacante quiere.
El CSRF se diferencia de otros ataques porque no necesita robar credenciales ni romper el cifrado. Explota la confianza de la víctima en la web. Como la víctima ya está autenticada, la web confía en las peticiones que parecen venir de ella.
Cómo funcionan los ataques CSRF
Un ataque CSRF ocurre en tres pasos.
Paso 1: la víctima tiene la sesión iniciada en tu sitio
Alguien visita tu web e inicia sesión en su cuenta. Su navegador ahora tiene una cookie de sesión activa que demuestra que está autenticado. Esa sesión sigue activa mientras siga usando el sitio.
Paso 2: el atacante le engaña para que visite una página maliciosa
Con la sesión aún abierta en tu sitio, la víctima visita una página que controla el atacante (quizá un enlace de redes sociales, un anuncio engañoso o una web que parece legítima). En esa página hay un código oculto que envía un formulario a tu sitio.
Paso 3: el formulario se envía solo con la sesión de la víctima
El formulario oculto se envía a tu web. Como la víctima ya tiene la sesión iniciada, su navegador incluye automáticamente su cookie de sesión en la petición. Desde el punto de vista de tu formulario, es una petición legítima de un usuario autenticado. El formulario la procesa como si la víctima lo hubiera enviado a propósito.
El atacante ha hecho algo en tu sitio con la cuenta de la víctima sin que ella lo sepa. Pudo cambiar su contraseña, transferir dinero, actualizar su perfil o enviar datos.
Por qué funciona aunque haya otras medidas de seguridad
Los ataques CSRF esquivan varias funciones de seguridad habituales:
HTTPS no frena el CSRF. Los datos viajan cifrados, pero el atacante no necesita interceptarlos. Solo envía la petición desde el navegador de la víctima, en el que el propio navegador ya confía.
La protección con contraseña no frena el CSRF. El atacante nunca necesita la contraseña de la víctima. Solo aprovecha que la víctima ya tiene la sesión iniciada.
Un buen sistema de inicio de sesión no frena el CSRF. Aunque la autenticación sea perfecta, si la víctima tiene la sesión iniciada, el ataque funciona.
Por eso la protección contra el CSRF es una capa propia. Las demás medidas de seguridad no la cubren. Tienes que diseñar los formularios para que resistan este ataque.
Tokens CSRF: cómo detienen el ataque
La solución es un token CSRF. Es una cadena única e impredecible que tu servidor genera para cada formulario. Así funciona:
Tu servidor crea un token único para cada visitante
Cuando alguien carga una página con un formulario, tu servidor genera un token aleatorio y lo asocia a la sesión de ese usuario. El token es distinto cada vez y exclusivo de ese usuario.
El token va dentro del formulario
El token se incluye como campo oculto en el formulario HTML. Cuando el visitante envía el formulario, el token viaja con él.
Tu servidor verifica el token antes de procesar el envío
Cuando se envía el formulario, tu servidor comprueba si el token del envío coincide con el que generó para la sesión de ese usuario. Si coincide, el formulario se procesa. Si no (o si no hay token), se rechaza.
El formulario oculto del atacante no puede incluir un token válido, porque los tokens son impredecibles y únicos para cada sesión. Un atacante en otro dominio no puede ver ni adivinar el token. Por eso su ataque falla. El formulario oculto se envía, pero tu servidor lo rechaza porque el token no coincide.
Cómo se ve un token CSRF en la práctica
En HTML, un formulario protegido contra CSRF tiene este aspecto:
<form method="POST" action="/submit-form"> <input type="hidden" name="csrf_token" value="a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"> <input type="email" name="email" placeholder="Your email"> <button type="submit">Submit</button> </form> El campo `csrf_token` está oculto. El visitante no lo ve, pero se envía junto con los datos del formulario. Tu servidor lo comprueba antes de procesar el correo o cualquier otro dato.
Protección CSRF según el tipo de formulario
Formularios HTML tradicionales
Los formularios HTML estándar (los que envían datos a tu servidor con POST) necesitan tokens CSRF. Esto incluye formularios de contacto, de inicio de sesión, de restablecimiento de contraseña y cualquier formulario que cambie datos en tu servidor.
Formularios AJAX y JavaScript
Los formularios que se envían con JavaScript a un endpoint de una API también necesitan protección CSRF. El token puede ir dentro del propio formulario, guardarse en una cookie u obtenerse de una metaetiqueta antes de enviar la petición.
Peticiones de API sin estado
Si tu API usa autenticación basada en tokens (como JWT), la protección CSRF funciona de otra manera. El navegador no puede adjuntar automáticamente un token JWT como hace con una cookie de sesión, así que el CSRF tradicional es una amenaza menor. Aun así, lo recomendable es incluir un token CSRF adicional para mayor protección.
Otras protecciones que funcionan junto con los tokens CSRF
Los tokens CSRF son la defensa principal, pero funcionan mejor junto con otras prácticas de seguridad.
Cookies SameSite
Al definir una cookie de sesión, puedes añadir un atributo `SameSite` que indica al navegador que no incluya la cookie cuando la petición venga de otro dominio. Así el formulario oculto del atacante no puede usar la sesión de la víctima.
Comprobación de la cabecera Referer
Tu servidor puede comprobar la cabecera Referer para ver de dónde viene la petición. Si un envío dice venir de tu dominio pero el Referer muestra otro, probablemente sea un ataque. (Sin embargo, las cabeceras Referer se pueden falsificar, así que esta no es una defensa completa.)
Patrón de cookie de doble envío
En este método, el token CSRF se guarda tanto en una cookie como en un campo del formulario. Tu servidor comprueba que coinciden antes de procesar. Es menos común que los tokens tradicionales, pero funciona bien en aplicaciones sin estado.
Cómo implementar la protección CSRF
Los detalles dependen de tu tecnología, pero el patrón es el mismo:
- Genera un token único por sesión. Cuando un usuario inicia sesión o carga una página con formulario, tu backend genera un token nuevo.
- Guarda el token en el servidor. Guárdalo asociado a la sesión de ese usuario.
- Incluye el token en el formulario. Añádelo como campo oculto en el HTML o como metaetiqueta que JavaScript pueda leer.
- Valida al enviar. Antes de procesar los datos del formulario, comprueba que el token enviado coincide con el guardado para esa sesión.
- Regenera el token tras las acciones sensibles. Cuando un usuario cambie su contraseña o haga algo crítico, genera un token nuevo.
La mayoría de los frameworks modernos generan y validan los tokens CSRF automáticamente. Si usas un framework, la protección CSRF suele estar activada por defecto. Solo asegúrate de no desactivarla sin querer.
Errores comunes que dejan los formularios vulnerables
Desactivar la protección CSRF por comodidad. Algunos desarrolladores apagan las comprobaciones CSRF para probar la API con más facilidad o simplificar el código. No lo hagas. Crea una vulnerabilidad real.
Usar un token estático para todos los usuarios. El token debe ser único para la sesión de cada usuario. Un token igual para todos (o igual para todos los usuarios todos los días) no protege contra el CSRF.
No regenerar los tokens. Si usas el mismo token durante semanas, el atacante tiene más tiempo para aprovecharlo. Regenera los tokens con regularidad y siempre después de operaciones sensibles.
Confiar solo en las cookies SameSite. SameSite ayuda, pero no basta. Usa los tokens CSRF como defensa principal y SameSite como respaldo.
Olvidar los tokens en algunos formularios. Si proteges unos formularios con tokens y otros no, los atacantes usarán los desprotegidos. Todo formulario que modifique datos necesita protección.
Qué hace WEMASY para la protección CSRF
Los formularios de WEMASY incluyen automáticamente protección con token CSRF en cada formulario que creas. No tienes que configurarla ni pensar en ella. Cuando un visitante envía un formulario, WEMASY valida el token antes de guardar el envío. Esta protección viene integrada y activada por defecto.
Descubre más sobre las opciones de seguridad de los formularios en la página de precios.