El CSRF aprovecha un automatismo del navegador: en cada petición a un sitio, adjunta las cookies de ese sitio, incluida la cookie de sesión. Una página externa puede, por tanto, lanzar una petición hacia tu sitio, y el servidor la recibe con las credenciales de la persona conectada. Nada la distingue de un clic voluntario, salvo que el sitio compruebe que procede de sus propios formularios. MITRE lo cataloga con el identificador CWE-352; también se escribe XSRF.
Cómo funciona un ataque CSRF
El atacante prepara una página que contiene una petición al sitio objetivo: una imagen invisible cuya URL desencadena una acción, o un formulario oculto que JavaScript envía automáticamente. Solo le queda atraer a la víctima a esa página, con un enlace en un correo, un comentario o un mensaje. Si en ese momento tiene la sesión iniciada en el sitio objetivo, la petición sale con su sesión.

Como subraya OWASP, el atacante no ve la respuesta del servidor. El CSRF apunta, por tanto, a las peticiones que cambian algo: modificar el correo de una cuenta, cambiar un ajuste, crear un usuario, borrar un contenido. En la administración de un sitio WordPress, estas acciones suelen bastar para hacerse con el control.
El papel de las cookies SameSite
El atributo SameSite de las cookies limita su envío desde otro sitio. Con Strict, la cookie solo acompaña a las peticiones del mismo sitio; con Lax, también se envía en una navegación de primer nivel con un método seguro, como un simple enlace GET. MDN precisa que algunos navegadores aplican Lax por defecto cuando falta el atributo. Es una protección útil, pero parcial: una acción lanzada por un enlace GET sigue pasando, y no todos los navegadores se comportan igual. Se suma, por tanto, a los tokens anti-CSRF, sin sustituirlos.
En WordPress: nonces y control de permisos
WordPress protege sus formularios y enlaces de acción con nonces: tokens ligados al usuario, a su sesión y a la acción solicitada, que un sitio de terceros no puede adivinar. Su vida útil es de 24 horas por defecto, dividida en dos periodos de 12 horas. Un plugin que añade sus propias acciones debe usarlos también:
// En el formulario
wp_nonce_field( 'miplugin_guardar', 'miplugin_nonce' );
// Al procesarlo
check_admin_referer( 'miplugin_guardar', 'miplugin_nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( 'Acceso denegado' );
}
wp_nonce_field()ywp_nonce_url()añaden el token a un formulario o a una URL;check_admin_referer()lo comprueba en la administración,check_ajax_referer()en una petición AJAX ywp_verify_nonce()en los demás casos;current_user_can()sigue siendo obligatorio: la documentación de WordPress recuerda que un nonce no sirve ni para la autenticación ni para el control de acceso.
Cómo protegerte como propietario
Los nonces olvidados siguen siendo habituales en los plugins: el CSRF figura entre las categorías de vulnerabilidades que se publican con regularidad, como muestran las cifras sobre vulnerabilidades en plugins de WordPress. Como propietario, los reflejos son sencillos: actualizar, no abrir enlaces desconocidos mientras tienes una sesión de administración abierta, cerrar sesión después de una intervención y no multiplicar las cuentas de administrador. Ni WP Masquerade ni un ajuste del Escritorio corrigen un nonce que falta en un plugin: solo su actualización lo hace.
Errores frecuentes
- Comprobar el nonce sin comprobar los permisos: un suscriptor conectado que obtiene un nonce válido, mostrado en una página a la que tiene acceso, puede llamar a una acción reservada a los administradores. Es la puerta abierta a vulnerabilidades de tipo IDOR o de control de acceso.
- Modificar datos con una simple petición GET, que pasa incluso con cookies
SameSite=Lax. - Olvidar que una vulnerabilidad XSS anula la protección: un script ejecutado en la página lee los nonces que contiene.
- Confundir CSRF y clickjacking: este último hace que la víctima haga clic en tu página real, mostrada en un marco invisible, algo que un nonce no impide.