
Un WordPress puede estar protegido con una buena contraseña, doble factor de autenticación y un formulario de acceso escondido, y aun así quedar expuesto si alguien roba una cookie de sesión válida. No necesita romper la contraseña. No necesita superar el 2FA. Ni siquiera tiene que atacar directamente el servidor. Le basta con reutilizar la cookie que demuestra que un administrador ya había iniciado sesión.
Ese ataque se conoce como secuestro de sesión o, en su forma más directa, pass-the-cookie. La idea es incómodamente sencilla: cuando WordPress ya ha comprobado que una persona es quien dice ser, deja una cookie en el navegador para no pedir usuario, contraseña y segundo factor en cada clic. Esa cookie funciona como una acreditación temporal. Si otra persona la copia y consigue usarla antes de que caduque o sea invalidada, puede aparecer ante WordPress como el usuario legítimo.
No es una rareza de laboratorio. MITRE lo recoge como técnica T1539, “Steal Web Session Cookie”, y organismos como el FBI han advertido de que los ciberdelincuentes roban cookies para esquivar la autenticación multifactor. En WordPress, donde muchas webs dependen de equipos personales poco protegidos, navegadores llenos de extensiones y sesiones largas con “Recuérdame”, el riesgo es muy real.
Cuando un usuario entra en WordPress, el sistema valida credenciales y, si existe, también el segundo factor. Superado ese paso, WordPress crea cookies de autenticación para mantener la sesión abierta. La más conocida para el uso general del sitio es wordpress_logged_in_[hash]. Para el área de administración se usan cookies de autenticación más restringidas, como las asociadas a wordpress_[hash] o wordpress_sec_[hash] cuando se trabaja bajo HTTPS.
Esas cookies no son simples textos al azar. WordPress genera valores firmados usando información del usuario, una fecha de expiración, un token de sesión y claves secretas del sitio. Esas claves, conocidas como salts o authentication keys, viven normalmente en wp-config.php y hacen que un atacante no pueda fabricar una cookie válida desde cero sin conocer los secretos de la instalación.
| Elemento | Qué función cumple |
|---|---|
| Cookie de login | Mantiene al usuario autenticado |
| Token de sesión | Identifica una sesión concreta |
| Fecha de expiración | Marca hasta cuándo puede usarse |
| Salts de WordPress | Ayudan a firmar y validar cookies |
| Hash de contraseña | Hace que cambiar contraseña invalide sesiones |
| HTTPS | Evita que la cookie viaje en claro |
| HttpOnly | Impide que JavaScript lea la cookie |
Desde WordPress 4.0, además, el sistema gestiona tokens de sesión. Eso permite cerrar sesiones concretas o cerrar todas las sesiones de un usuario. El botón “Cerrar sesión en el resto de sitios”, disponible en el perfil del usuario, se apoya precisamente en esa lógica.
El detalle importante es este: el 2FA protege el momento del login. Una cookie robada ya representa una sesión que superó ese login. Por eso el segundo factor no se dispara otra vez si WordPress interpreta que la sesión sigue siendo válida.
Hay una frase que se repite mucho: “un XSS roba la cookie de sesión”. Como explicación general de seguridad web puede servir, pero en WordPress hay que matizarla. Las cookies de autenticación de WordPress usan el atributo HttpOnly, lo que impide que un script ejecutado en el navegador pueda leerlas mediante document.cookie.
Puedes comprobarlo en segundos: abre una sesión en WordPress, entra en la consola del navegador y ejecuta:
document.cookieLenguaje del código: JavaScript (javascript)
No deberían aparecer las cookies de autenticación sensibles. Eso no significa que un XSS sea inofensivo. Significa que el daño habitual no consiste en “ver” la cookie, sino en actuar dentro de una sesión ya abierta. Un script malicioso ejecutado en el navegador de un administrador puede intentar crear usuarios, cambiar ajustes o enviar peticiones en nombre de ese administrador, sin necesidad de leer la cookie.
Por tanto, HttpOnly ayuda contra el robo directo por JavaScript, pero no convierte un XSS en un problema menor. Un XSS en el panel o en una página visitada por administradores sigue siendo una incidencia seria.
En muchos casos, el robo no ocurre dentro de WordPress, sino en el equipo desde el que se administra la web. Esa es la parte que más se subestima. Puedes tener el servidor parcheado y aun así perder la sesión si el ordenador del administrador está comprometido.
| Vía de robo | Qué ocurre |
| Infostealer en el equipo | Malware lee cookies, contraseñas y tokens guardados en el navegador |
| Phishing con proxy AiTM | El usuario inicia sesión en una página intermediaria y el atacante captura la sesión |
| HTTP sin cifrar | La cookie puede viajar en claro si no se fuerza HTTPS |
| Extensión maliciosa | Una extensión con permisos amplios puede acceder a datos del navegador |
| Equipo compartido o sin bloquear | Alguien con acceso físico puede reutilizar la sesión |
| Copias de perfil de navegador | Backups o perfiles sincronizados mal protegidos pueden filtrar sesiones |
Los infostealers son una de las vías más peligrosas porque no atacan tu WordPress directamente. Atacan el navegador. Familias como Lumma, RedLine, Vidar o similares se especializan en extraer credenciales, cookies, monederos, datos de sesión y otra información útil. El atributo HttpOnly no sirve frente a un programa que lee directamente la base de datos local del navegador.
El phishing adversary-in-the-middle, o AiTM, funciona de otra forma. El atacante coloca una página intermedia que replica el login real. La víctima introduce usuario, contraseña y 2FA, y el proxy traslada todo al sitio legítimo en tiempo real. Cuando el sitio real devuelve la sesión válida, el atacante captura el token o cookie resultante. El usuario cree que ha iniciado sesión normalmente; el atacante ya tiene una sesión aprovechable.
La ventana de ataque depende de la duración de la sesión. WordPress permite controlar la expiración mediante auth_cookie_expiration. En términos generales, cuando se marca “Recuérdame”, la sesión persistente dura 14 días por defecto. Sin “Recuérdame”, WordPress usa una cookie de sesión del navegador, con un límite interno de expiración.
Para reducir la ventana de exposición, se puede acortar la duración de las sesiones. En una web con varios administradores, un día puede ser un compromiso razonable:
// Acortar la duración de la cookie de autenticación a 1 día.
function nh_short_auth_cookie_expiration( $expiration, $user_id, $remember ) {
return DAY_IN_SECONDS;
}
add_filter( 'auth_cookie_expiration', 'nh_short_auth_cookie_expiration', 10, 3 );Lenguaje del código: PHP (php)
En entornos donde el panel de administración se usa poco, se puede ser incluso más estricto. Eso sí, hay que equilibrar seguridad y operativa: si la expiración es demasiado corta, los usuarios buscarán atajos peores, como dejar sesiones abiertas en equipos compartidos.
La defensa no depende de una sola medida. Hay que combinar configuración de WordPress, seguridad del navegador, higiene del equipo y controles de infraestructura.
| Medida | Qué reduce |
| Forzar HTTPS en todo el sitio | Robo por red e intercepción básica |
Usar Secure y HttpOnly | Exposición de cookies en cliente |
| Añadir SameSite donde proceda | Riesgo de CSRF y uso cruzado no deseado |
| Evitar “Recuérdame” en administradores | Ventana de explotación |
| Cerrar sesión al terminar | Persistencia innecesaria |
| Acortar expiración de cookies | Tiempo útil de una cookie robada |
| Rotar salts ante sospecha | Invalida sesiones y nonces |
| Cambiar contraseñas | Invalida cookies ligadas al hash anterior |
| Revisar usuarios administradores | Detecta persistencia creada por el atacante |
| Monitorizar actividad | Permite ver acciones anómalas |
| Proteger el equipo del administrador | Corta infostealers y extensiones maliciosas |
Limitar /wp-admin por IP o VPN | Reduce superficie de acceso |
Para forzar HTTPS en el panel, WordPress permite usar:
define( 'FORCE_SSL_ADMIN', true );Lenguaje del código: JavaScript (javascript)
También conviene activar HSTS desde el servidor o CDN cuando todo el sitio esté correctamente en HTTPS. No basta con que el certificado exista; hay que evitar que el login o partes del sitio sigan accesibles por HTTP.
Para cerrar sesiones de un usuario desde WP-CLI:
wp user session destroy usuario --all
Para rotar salts con WP-CLI:
wp config shuffle-salts
Rotar salts no previene el robo, pero es un interruptor de emergencia. Cierra sesiones y fuerza nuevos logins. Hay que usarlo cuando hay sospecha de compromiso, no como rutina diaria sin pensar.
Decir que el 2FA no evita el pass-the-cookie no significa que sobre. Todo lo contrario. El 2FA sigue bloqueando ataques de contraseña robada, fuerza bruta, reutilización de credenciales y accesos básicos al login. Lo que no hace es proteger una sesión ya creada si esa sesión se roba después.
La defensa moderna contra este problema apunta hacia sesiones ligadas al dispositivo. Google ha empezado a desplegar Device Bound Session Credentials en Chrome, una tecnología que intenta que una cookie robada no pueda usarse fuera del dispositivo original porque la sesión queda vinculada criptográficamente al equipo. Es una dirección prometedora, pero no sustituye las medidas básicas en WordPress ni está integrada de forma universal en todas las webs.
También ayuda usar autenticación resistente al phishing, como passkeys o llaves FIDO2, porque dificultan los ataques AiTM contra el login. Aun así, si el equipo del administrador está infectado, el problema no se resuelve solo con cambiar el método de autenticación. Un dispositivo comprometido puede seguir siendo el punto débil.
No siempre es fácil. Para WordPress, una cookie válida parece una sesión legítima. Por eso hay que mirar señales indirectas.
| Señal | Qué puede indicar |
| Accesos desde países o IPs raras | Reutilización remota de sesión |
| Cambios fuera de horario | Uso no reconocido de una cuenta |
| Usuarios administradores nuevos | Persistencia del atacante |
| Plugins instalados sin explicación | Intento de puerta trasera |
| Archivos modificados | Compromiso posterior al acceso |
| Cambios en reglas, redirecciones o SEO | Monetización del acceso |
| Actividad REST inusual | Uso abusivo de una sesión válida |
Un registro de actividad no evita el ataque, pero permite reconstruir qué pasó. En WordPress, conviene registrar logins, cambios de usuarios, instalación de plugins, edición de temas, cambios de ajustes, actividad REST y modificaciones de contenido. Sin ese registro, la investigación queda a ciegas.
La respuesta debe ser rápida. Si una cookie robada sigue viva, cada minuto cuenta.
| Orden | Acción |
| 1 | Rotar salts para invalidar sesiones y nonces |
| 2 | Cambiar contraseñas de administradores |
| 3 | Cerrar todas las sesiones de usuarios con privilegios |
| 4 | Revisar y borrar administradores desconocidos |
| 5 | Comprobar plugins, temas y archivos modificados |
| 6 | Revisar logs de actividad, servidor y CDN |
| 7 | Analizar el equipo desde el que se administra |
| 8 | Revisar extensiones del navegador y software instalado |
| 9 | Activar 2FA si no estaba activo |
| 10 | Endurecer expiración de sesión, IPs permitidas y HTTPS |
El error habitual es limpiar solo WordPress. Si el origen fue un infostealer, el atacante volverá a robar la nueva cookie en cuanto el administrador entre otra vez desde el mismo equipo infectado. Primero se corta el acceso, después se limpia WordPress y después se sanea el dispositivo.
El ataque contra cookies de sesión es peligroso porque se mueve justo después del punto donde solemos sentirnos seguros. La contraseña era buena. El 2FA estaba activo. El login no mostró errores. Pero la sesión ya autenticada se convirtió en la llave.
Para una web WordPress, la seguridad no acaba en el servidor. Empieza también en el portátil desde el que se entra al panel, en las extensiones del navegador, en el correo donde llegan enlaces falsos, en la costumbre de cerrar sesión y en la capacidad de invalidar sesiones cuando algo huele mal.
Si hoy solo se pueden hacer tres cosas, que sean estas: forzar HTTPS en toda la web, dejar de usar “Recuérdame” en cuentas administradoras y revisar desde qué equipos se entra al panel. Después vendrán la expiración de cookies, el registro de actividad, las reglas por IP, la rotación de salts y la monitorización.
La cookie no es un detalle técnico. Es la pulsera que demuestra que ya pasaste por la puerta. Si alguien la roba, la seguridad de la entrada ya no importa.
¿El 2FA protege contra el robo de cookies en WordPress?
No directamente. El 2FA protege el inicio de sesión, pero una cookie robada representa una sesión que ya pasó ese control. Aun así, el 2FA sigue siendo necesario contra contraseñas robadas y fuerza bruta.
¿Un XSS puede robar las cookies de WordPress?
Las cookies de autenticación usan HttpOnly, así que JavaScript no debería poder leerlas con document.cookie. Pero un XSS sigue siendo grave porque puede ejecutar acciones dentro de una sesión abierta.
¿Cambiar la contraseña invalida una cookie robada?
Sí, en la práctica ayuda a invalidar cookies ligadas al hash anterior de la contraseña. Ante sospecha, también conviene cerrar sesiones y rotar salts.
¿Rotar las salts de WordPress es una buena medida de emergencia?
Sí. Cambiar las salts de wp-config.php invalida sesiones y nonces, lo que fuerza a todos los usuarios a iniciar sesión de nuevo. Debe usarse con cuidado, pero es útil ante un compromiso.
Fuentes: AyudaWP, WordPress Developer Resources, WP-CLI, OWASP Session Management Cheat Sheet.
