El 17 de julio de 2026 se publicó el aviso de seguridad GHSA-ff9f-jf42-662q y, con él, la peor noticia posible para cualquiera que gestione webs en WordPress: una vulnerabilidad de ejecución remota de código sin autenticación y en el núcleo. Sin plugin culpable, sin configuración exótica, sin necesidad de que nadie haga clic en nada. Basta con que el sitio corra una versión afectada y responda peticiones HTTP. La comunidad la bautizó wp2shell: de WordPress a shell.
Una semana después, el panorama ya no admite matices. Las dos CVE que forman la cadena entraron en el catálogo KEV de CISA el 21 de julio —lo que significa explotación activa confirmada por la agencia estadounidense—, Searchlight Cyber publicó el análisis técnico completo el 22, y hay pruebas de concepto funcionales circulando en GitHub desde las primeras horas. El parche existe desde el minuto uno. El problema, como casi siempre, no es el parche: es cuánto tarda en llegar a las 40, 200 o 500 instalaciones que alguien tiene bajo su responsabilidad.
Este artículo tiene dos partes. La primera explica qué es wp2shell de verdad, sin el ruido de los titulares: qué hacen exactamente las dos vulnerabilidades, por qué solo son graves encadenadas, qué versiones están afectadas y qué está confirmado frente a lo que circula sin fuente. La segunda es la que nos parece más útil y la que casi nadie escribe: el protocolo. Qué hace una agencia —qué deberías hacer tú— en las horas siguientes a un aviso de este tipo, en qué orden, y cómo verificar después que el parche realmente se aplicó, porque en un porcentaje incómodo de casos no lo hace.
1. Cronología: qué pasó y en cuánto tiempo
La secuencia importa, porque explica por qué esta vez la ventana de reacción fue tan estrecha.
17 de julio. Se publica el aviso de seguridad en el repositorio de WordPress y salen las versiones correctivas 6.9.5 y 7.0.2. WordPress activa actualizaciones automáticas forzadas para las instalaciones afectadas que las tengan habilitadas. Searchlight Cyber, el equipo que descubrió la cadena, confirma que se explota en remoto contra una instalación por defecto, sin plugins adicionales.
18-20 de julio. Aparecen las primeras pruebas de concepto públicas. El diff entre la versión vulnerable y la parcheada es abierto —WordPress es software libre— y reconstruir el exploit a partir de ahí dejó de ser trabajo de días para pasar a ser trabajo de horas.
21 de julio. CISA incorpora CVE-2026-63030 y CVE-2026-60137 a su catálogo de vulnerabilidades explotadas conocidas (KEV). Es el sello administrativo de que ya no hablamos de riesgo teórico.
22 de julio. Searchlight Cyber publica el writeup técnico completo de la cadena. Rapid7 actualiza su aviso para reflejar explotación en la naturaleza y añade la recomendación de mitigación por WAF.
De divulgación a explotación masiva, menos de una semana. De parche disponible a exploit público, menos de veinticuatro horas.
2. Qué es wp2shell exactamente
wp2shell no es una vulnerabilidad, son dos. Y ese detalle no es una curiosidad taxonómica: es la clave para entender por qué se coló.

2.1 CVE-2026-63030: confusión de rutas en el batch API
WordPress expone desde hace varias versiones un endpoint que permite agrupar varias peticiones de la API REST en una sola llamada HTTP: /wp-json/batch/v1. Es funcionalidad legítima y necesaria —el editor de bloques la usa constantemente— y viene activa en cualquier instalación estándar.
El fallo está en cómo se procesa esa petición agrupada. La validación de las sub-peticiones y su ejecución recorren estructuras distintas. Cuando wp_parse_url() falla al analizar la ruta de una sub-petición, el error se registra en el array de validación pero no en el de coincidencias. Ese desfase desincroniza ambos arrays y, a partir de ahí, cada petición siguiente se despacha con el manejador equivocado. Es un fallo de lógica, no de memoria ni de permisos: el sistema hace lo que le pides, solo que con la rutina que no toca.
2.2 CVE-2026-60137: inyección SQL en author__not_in
El segundo fallo vive en WP_Query, la clase que construye la mayoría de las consultas a base de datos de WordPress. El parámetro author__not_in se interpola directamente en SQL crudo cuando llega como cadena escalar en lugar de como array. En condiciones normales, la validación de parámetros de la API impide que eso ocurra.
En condiciones normales. La desincronización del punto anterior permite saltarse esa validación, y una llamada batch recursiva esquiva además las restricciones sobre peticiones GET. Resultado: inyección SQL basada en UNION, ejecutable sin credenciales de ningún tipo.
2.3 Por qué la cadena es lo grave
Por separado, ninguna de las dos llega a ejecución de código. La confusión de rutas provoca un comportamiento anómalo del enrutado, pero no escribe nada. La inyección SQL permite leer y escribir en base de datos, que ya es serio, pero no da por sí sola una shell.
Juntas sí. Con la inyección activa se fabrica una cuenta de administrador, se inicia sesión con ella y desde el panel se sube un plugin malicioso. A partir de ese momento el atacante ejecuta código PHP con los permisos del usuario bajo el que corre el servidor web: acceso a la base de datos entera, al sistema de ficheros, y en hostings compartidos mal aislados, un punto de partida para moverse lateralmente.
Este patrón —dos fallos individualmente moderados que combinados dan control total— es exactamente el escenario que las revisiones de desarrollo seguro según ISO 27001 y el ENS intentan anticipar, y la razón por la que puntuar vulnerabilidades de forma aislada da una imagen incompleta del riesgo real.
3. Versiones afectadas y parches
Este es el bloque que hay que mirar antes que ningún otro:
| Rama | Versiones afectadas | ¿RCE completo? | Versión corregida |
|---|---|---|---|
| 6.8.x | 6.8.0 – 6.8.5 (solo CVE-2026-60137) | No | 6.8.6 |
| 6.9.x | 6.9.0 – 6.9.4 | Sí | 6.9.5 |
| 7.0.x | 7.0.0 – 7.0.1 | Sí | 7.0.2 |
| 7.1 beta | Betas anteriores a la 2 | Sí | 7.1 Beta 2 |
Dos matices que se pierden en los resúmenes. El primero: la rama 6.8.x también recibe parche. No está expuesta a la cadena completa porque le falta el primer fallo, pero sí arrastra la inyección SQL. Si diste por hecho que estabas fuera de alcance por no haber saltado a la 6.9, revisa igualmente.
El segundo: Cloudflare señaló que la ruta de código vulnerable de CVE-2026-63030 se alcanza cuando el sitio no usa un object cache persistente. Tener Redis o Memcached delante reduce la exposición, pero es una mitigación circunstancial: la configuración de caché puede cambiar mañana y el fallo sigue ahí. No es una razón para no parchear.
Sobre la puntuación conviene ser preciso, porque circulan cifras distintas y todas son «verdad». El aviso de GitHub clasifica CVE-2026-63030 como crítica; el CVSS asignado en NVD para esa CVE es 7.5. CVE-2026-60137, por su parte, puntúa 5.9. Y varios análisis puntúan la cadena completa en 9.8, que es lo que refleja el impacto real. La divergencia no es un error de nadie: es la consecuencia de un sistema de puntuación que evalúa vulnerabilidades sueltas en un mundo donde los ataques se construyen encadenándolas.
4. Lo confirmado, lo no confirmado y las cifras que circulan
Con una vulnerabilidad de este perfil, la mitad del trabajo consiste en separar hechos de ruido. A 26 de julio, la foto es esta.
Confirmado. Las dos CVE existen, están en el core y están parcheadas. Hay exploits públicos funcionales. Hay explotación activa: CISA las añadió al catálogo KEV el 21 de julio, y varias firmas de seguridad han documentado actividad real, no solo escaneo automatizado. Cloudflare desplegó reglas de WAF específicas.
No confirmado. No hay indicadores de compromiso (IoC) oficiales publicados: ni hashes de webshell conocidos ni patrones de nombre de fichero. Eso complica el trabajo forense y obliga a auditar en amplio en lugar de buscar una firma concreta. Tampoco hay atribución pública de quién está detrás de la explotación.
Y las cifras. Estos días circula por newsletters y redes que «6 de cada 10 webs estaban expuestas» en el momento de la publicación. La cifra es plausible como orden de magnitud —el grueso del parque está en las ramas 6.9 y 7.0, que son justo las afectadas—, pero conviene manejarla como lo que es: una estimación de terceros. WordPress no publica telemetría de adopción de parches y ninguna de las firmas de seguridad que han cubierto el caso ha dado un porcentaje verificable de sitios comprometidos. Nos parece más honesto decirlo así que repetir el dato como si fuera un censo.
Lo que sí es medible sin discusión es la persistencia de los escaneos. Si tienes acceso a los logs de tu servidor, mira cuántas peticiones a /wp-json/batch/v1 han entrado esta semana desde IPs que no reconoces. Ese número te dirá más sobre tu exposición real que cualquier porcentaje global.
5. El protocolo: qué hacer en las primeras 72 horas
Aquí es donde una agencia con cartera de mantenimiento se gana el contrato o lo pierde. Un aviso de core no se resuelve con «actualiza WordPress»: se resuelve con un procedimiento que ya estaba escrito antes de que llegara el aviso. Este es el nuestro, con los tiempos que consideramos razonables.

5.1 T+0 — El aviso llega de una fuente fiable
El primer requisito es enterarse, y enterarse por un canal técnico, no por el titular de un medio generalista dos días después. Suscripción al feed de seguridad de WordPress, al catálogo KEV de CISA y a los avisos de dos o tres firmas de referencia. Cuesta media hora configurarlo una vez y es la diferencia entre reaccionar el día 17 y reaccionar el día 21.
5.2 T+1h — Inventario: qué webs, qué versión, qué hosting
Si no tienes un inventario actualizado, este paso te come la mañana entera y ahí ya has perdido. Debería ser una consulta, no una investigación: listado de sitios, rama y versión exacta de cada uno, proveedor de hosting, si tiene WAF delante y si las actualizaciones automáticas están activas. Con eso se prioriza en minutos: primero las instalaciones 6.9.x y 7.0.x sin WAF y con acceso público, después el resto.
5.3 T+4h — Mitigación temporal antes que el parche
Parchear una cartera entera lleva horas; bloquear el vector lleva minutos. La mitigación recomendada por Rapid7 y aplicada por Cloudflare es cerrar el endpoint vulnerable en el firewall de aplicación: /wp-json/batch/v1 y su forma alternativa ?rest_route=/batch/v1. Se puede hacer en el WAF del proveedor, en Cloudflare o directamente en el servidor —una regla location en nginx o una directiva en .htaccess—.
Dos advertencias. La primera: no desactives la API REST completa. Gutenberg, WooCommerce y decenas de plugins dependen de /wp-json y te vas a romper el sitio. La segunda: una regla de WAF frena los exploits genéricos, no las variantes que modifican la estructura de la petición para esquivar firmas. Es un parachoques, no una solución. La lógica es la misma que explicamos al hablar de protección DDoS por capas: cada capa compra tiempo, ninguna sustituye a la de abajo.
5.4 T+12h — El parche, con copia de seguridad previa
Actualizar a 6.8.6, 6.9.5 o 7.0.2 según la rama. Antes, una copia de seguridad; después, otra. Si el sitio estuvo expuesto y acaba apareciendo un compromiso, un backup anterior a la ventana de exposición es el único punto de restauración limpio que vas a tener. Un backup tomado después no sirve: restaura el problema.
Con acceso SSH, wp core update --version=7.0.2 --force resuelve los casos en los que el actualizador del panel falla. En instalaciones con despliegue por Git o con el core versionado, el proceso pasa por la rama de despliegue habitual y no por wp-admin.
5.5 T+24h — Verificar la versión real, no la que dice el panel
Este paso es el que más veces se salta y el que más disgustos ahorra. WordPress empujó actualizaciones forzadas, pero «forzada» no es «garantizada»: si el hosting tiene restricciones de escritura en disco, permisos mal configurados, un sistema de staging con aprobación manual o una caché agresiva, la actualización puede no haberse aplicado aunque el proceso reporte éxito.
Verifica la versión real de cada sitio, idealmente de forma programática: wp core version por SSH, o una consulta al endpoint de la API. Si gestionas decenas de webs, un script que recorra el inventario y devuelva versión por sitio es media hora de trabajo que se amortiza en la primera emergencia.
5.6 T+72h — Auditoría de compromiso
El parche cierra la puerta. No echa a quien ya estaba dentro. Si alguno de tus sitios corrió una versión vulnerable durante la ventana de explotación activa, hay que revisarlo aunque no se vea nada raro: las puertas traseras bien puestas no hacen ruido, y pueden esperar semanas antes de usarse.
¿Sabes en qué versión están hoy todas tus webs?
En Keliam mantenemos carteras de sitios WordPress y WooCommerce con inventario, parcheo verificado y auditoría de compromiso cuando aparece un aviso como wp2shell. Si tu web estuvo expuesta y no sabes si entraron, la revisión forense es el primer paso.
6. Cómo comprobar si te han entrado
Sin IoC oficiales, la auditoría tiene que ser amplia. Estos son los seis puntos que revisamos, ordenados por relación entre esfuerzo y probabilidad de encontrar algo:
Usuarios administradores. Panel de Usuarios, filtro por rol Administrador. Cualquier cuenta que no reconozcas es señal de compromiso, y en esta cadena concreta la creación de un admin es un paso obligado del ataque. Revisa también las fechas de registro: una cuenta creada entre el 17 y el día en que parcheaste merece explicación.
Ficheros PHP en /wp-content/uploads. La carpeta de medios no debería contener un solo .php. Si hay alguno, con altísima probabilidad es una webshell. Busca también en subcarpetas por año y mes, que es donde suelen esconderse.
Integridad del core. wp core verify-checksums compara los hashes de tus ficheros del núcleo contra los oficiales. Cualquier diferencia es sospechosa, y es la comprobación más barata de todas.
Plugins que no instalaste. Como la escalada pasa por subir un plugin malicioso, revisa el listado completo, incluidos los desactivados, y compáralo con lo que debería haber. Un plugin con nombre plausible y sin entrada en el repositorio oficial es una bandera roja.
Logs de acceso al endpoint batch. Peticiones POST a /wp-json/batch/v1 o a ?rest_route=/batch/v1 desde IPs externas. Un volumen alto indica escaneo; peticiones seguidas de escrituras en disco indican algo peor. Si no sabes por dónde empezar a leer logs, el enfoque que describimos en ciberseguridad de servidores con poco presupuesto incluye por dónde empezar.
Tareas programadas y contenido inyectado. Revisa wp cron event list en busca de eventos que no reconozcas, y prueba a acceder al sitio en incógnito simulando un móvil o llegando desde un buscador: el spam SEO suele mostrarse solo a esos perfiles.
Si encuentras evidencia, el orden es: aislar el sitio, restaurar desde una copia anterior al 17 de julio, cambiar todas las credenciales —WordPress, base de datos, FTP/SSH, panel de hosting— y solo entonces actualizar al core parcheado. Restaurar sin rotar credenciales es tirar el trabajo: si el atacante se llevó los accesos, vuelve a entrar por la puerta.
Un apunte que se olvida con frecuencia: si el sitio trata datos personales y hay indicios de acceso no autorizado, se abre un reloj regulatorio. La obligación de notificar a la autoridad de control en 72 horas es del RGPD, y en determinados sectores se suma el régimen de notificación de incidentes que describimos en el artículo sobre las obligaciones de NIS2 para empresas tecnológicas. La respuesta técnica y la respuesta legal empiezan a la vez.
7. Lo que wp2shell cambia de aquí en adelante
La gravedad técnica no es lo más significativo de este episodio. Ha habido RCE en el core de WordPress antes. Lo nuevo es la velocidad.
Searchlight Cyber ha explicado abiertamente que en su investigación se apoyó en modelos de lenguaje para explorar la superficie de ataque. Y del otro lado ocurrió lo mismo: los primeros PoC públicos aparecieron en horas, no en días, porque analizar el diff entre la versión vulnerable y la parcheada y convertirlo en exploit funcional es exactamente el tipo de tarea en la que estas herramientas rinden bien.
La consecuencia operativa es incómoda pero clara: la ventana entre «hay parche» y «hay exploit al alcance de cualquiera» se ha comprimido a horas. El modelo mental de «actualizo el primer lunes de cada mes» ya no funciona para vulnerabilidades de core con explotación remota. O tienes actualizaciones automáticas de seguridad activas y verificadas, o tienes un procedimiento que se dispara en el mismo día, o vas tarde por diseño.
Esto empuja en una dirección concreta a cualquiera que gestione más de un puñado de sitios: automatizar, inventariar y monitorizar. No como buenas intenciones, sino como infraestructura. La misma lógica de defensa en capas que aplicamos en seguridad informática para pymes desde cero —cada capa asume que la anterior puede fallar— es la que hace que un aviso como este sea una tarde de trabajo y no una crisis.
8. Hardening que reduce el impacto del próximo aviso
Ninguna de estas medidas habría evitado wp2shell. Todas habrían reducido su impacto, y van a reducir el del siguiente:
Impedir la ejecución de PHP en uploads. Una directiva en el servidor que desactive el motor PHP dentro de /wp-content/uploads hace que, aunque un atacante consiga escribir una webshell ahí, no pueda ejecutarla. Es defensa en profundidad barata y sin efectos secundarios.
Actualizaciones automáticas de seguridad activas y verificadas. Activadas no basta: hay que comprobar periódicamente que se aplican. Un informe mensual de versiones por sitio detecta las instalaciones donde el mecanismo lleva meses fallando en silencio.
Monitorización de integridad de ficheros. Herramientas como Wordfence o el módulo de integridad de Sucuri avisan cuando aparece o cambia un fichero en el core o en wp-content. Un PHP nuevo en uploads es justo el evento que quieres ver en tiempo real, no tres semanas después.
Restringir la API REST anónima donde no haga falta. Muchos sitios corporativos no necesitan que usuarios no autenticados consuman /wp-json. Cerrarlo reduce superficie para toda una familia de vulnerabilidades futuras, aunque en este caso concreto no habría bastado.
WAF delante, con reglas actualizadas. Y una pregunta incómoda para tu proveedor de hosting: ¿te avisó de wp2shell en las primeras 24 horas y publicó reglas propias? Algunos lo hicieron. La respuesta te dice bastante sobre qué esperar en la próxima emergencia. Si tu infraestructura es propia, el enfoque de poner un firewall delante de la red aplica igual a nivel de aplicación.
Copias de seguridad probadas. No que existan: que se hayan restaurado alguna vez en un entorno de prueba. Es la única forma de saber que el plan B funciona antes de necesitarlo, y el mismo criterio que aplicamos frente a un incidente de ransomware.
Inventario vivo. Suena a burocracia hasta el día en que tienes que responder «¿cuántas de nuestras webs están en 7.0.1?» en menos de una hora. Ese día vale todo lo que costó mantenerlo.
Conclusión
wp2shell es grave por dónde está —el núcleo, no un plugin— y por lo rápido que pasó de aviso a exploit al alcance de cualquiera. Pero la lección práctica no va de esta vulnerabilidad concreta, que ya tiene parche desde el 17 de julio. Va de que el ciclo de respuesta se ha acortado tanto que la única defensa sostenible es tenerlo automatizado antes de que suene la alarma.
Si gestionas una web: comprueba la versión hoy, no la que dice el panel sino la real, y si estuviste en 6.9.x o 7.0.x sin parchear entre el 17 y el día que actualizaste, haz la revisión de compromiso aunque no veas nada raro. Si gestionas cuarenta: lo que necesitas no es parchear más rápido, es tener el inventario, el WAF y la verificación montados de forma que parchear rápido sea la consecuencia y no el esfuerzo.
Y si has llegado hasta aquí sin saber en qué versión está tu WordPress, ese es exactamente el problema que hay que resolver primero. Nuestra guía de seguridad de WordPress para empresas y la guía de actualización a WordPress 7 cubren el terreno de fondo; este artículo cubre la emergencia.
Preguntas frecuentes sobre wp2shell
¿Qué versión de WordPress corrige wp2shell?
Depende de tu rama: 6.8.6 corrige la inyección SQL en la rama 6.8.x; 6.9.5 y 7.0.2 corrigen la cadena completa en 6.9.x y 7.0.x respectivamente. La rama 7.1 incluye el arreglo desde la Beta 2. Cualquier versión anterior a esas es vulnerable al menos a uno de los dos fallos.
Tengo las actualizaciones automáticas activadas, ¿estoy protegido?
Probablemente sí, pero verifícalo. WordPress forzó la actualización, aunque puede no haberse aplicado si el hosting tiene restricciones de escritura, permisos mal configurados o un flujo de staging con aprobación manual. Comprueba el número de versión real antes de darlo por hecho.
Estoy en WordPress 6.8, ¿me afecta?
Parcialmente. La rama 6.8.x no está expuesta a la ejecución remota de código porque le falta el primer fallo de la cadena, pero sí arrastra CVE-2026-60137, la inyección SQL. El parche correspondiente es la versión 6.8.6.
¿Basta con bloquear el endpoint /wp-json/batch/v1?
Como medida temporal, ayuda. Como solución, no. Bloquear el endpoint en el WAF frena los exploits genéricos mientras preparas la actualización, pero no cubre variantes que modifiquen la estructura de la petición. La protección real es el parche.
Mi web estuvo sin actualizar varios días, ¿cómo sé si me atacaron?
Revisa cuentas de administrador que no reconozcas, ficheros PHP en /wp-content/uploads, plugins que no instalaste, y ejecuta wp core verify-checksums. Busca también peticiones POST al endpoint batch en los logs del servidor. Como no hay indicadores de compromiso oficiales publicados, la revisión tiene que ser amplia.
¿Puede afectar también a WooCommerce o a otras tiendas sobre WordPress?
Sí, porque el fallo está en el núcleo, no en el plugin. Una tienda WooCommerce sobre una versión afectada es vulnerable igual que cualquier otro sitio, con el agravante de que el impacto incluye datos de clientes y pedidos. Si es tu caso, la revisión posterior debería seguir el enfoque de una auditoría de seguridad en ecommerce.
Fuentes
- Aviso de seguridad de WordPress GHSA-ff9f-jf42-662q y notas de las versiones 6.9.5 y 7.0.2 (WordPress.org, 17 de julio de 2026).
- Rapid7 Labs, CVE-2026-63030: wp2shell, a Critical Remote Code Execution Vulnerability in WordPress Core (17 de julio, actualizado el 22).
- Searchlight Cyber, análisis técnico completo de la cadena de explotación (22 de julio).
- CISA, catálogo Known Exploited Vulnerabilities: CVE-2026-63030 y CVE-2026-60137 (21 de julio).
- Cloudflare, análisis del vector y despliegue de reglas de WAF.
- Tenable, FAQ sobre wp2shell y limitaciones de las actualizaciones automáticas forzadas.



