RCE en WordPress Core durante la ventana de actualización, corregido en 7.1.4 (CVE-2026-119977)
WordPress 4.7 a 7.1.3 descomprime las actualizaciones en una ruta web predecible que permite ejecutar código a atacantes no autenticados que ganen la carrera; corregido en 7.1.4.
Resumen
- Una falla en el actualizador de WordPress Core permite a un atacante no autenticado ejecutar código en el servidor durante la ventana de segundos en la que WordPress descomprime una actualización del núcleo. Las versiones 4.7.0 a 7.1.3 están afectadas. Umut Bayram de Picus Security la divulgó de forma responsable.
- El registro CVE de Wordfence puntúa la falla 8.1 High, CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H, y el aviso del propio WordPress puntúa la misma carrera Low. Wordfence bloqueó 62,969 ataques dirigidos a ella en 24 horas al 30 de octubre.
- La corrección llegó en WordPress 7.1.4, publicado el 28 de octubre de 2026, y se retroportó a cada rama hasta 4.7. No se reporta ningún compromiso, y el CVE no está en el catálogo KEV (Known Exploited Vulnerabilities) de CISA al 31 de octubre de 2026.
- Actualice a 7.1.4 o al retroportado de su rama ahora, y luego busque en los registros de su servidor web las peticiones a archivos PHP bajo
wp-content/upgrade. Los sitios sin el parche abren una ventana vulnerable en cada actualización, incluida la propia actualización a 7.1.4.
¿Estoy afectado?
Todas estas condiciones deben cumplirse para el ataque no autenticado:
- Su sitio ejecuta WordPress 4.7.0 a 7.1.3, en cualquiera de las ramas listadas abajo.
- Su sitio aplica actualizaciones del núcleo a través del actualizador de WordPress, que descomprime un paquete completo en
wp-content/upgrade/en el servidor web. - Ese directorio es accesible por el web, algo que Wordfence señala que ocurre en muchos servidores, y sus archivos se ejecutan como PHP.
- El atacante gana la carrera: debe alcanzar los archivos extraídos entre la descompresión y la limpieza, una ventana que Wordfence observó que dura solo segundos en entornos de laboratorio.
La ruta es predecible en todas las versiones afectadas, así que la cuarta condición depende del momento, no del conocimiento. El atacante no necesita ninguna cuenta en el sitio ni interacción de nadie.
| Rama | Versiones afectadas | Versión corregida |
|---|---|---|
| WordPress 7.1.x | 7.1.0 a 7.1.3 | 7.1.4 |
| WordPress 7.0.x | 7.0.0 a 7.0.7 | 7.0.8 |
| WordPress 6.9.x | 6.9.0 a 6.9.10 | 6.9.11 |
| WordPress 6.8.x | 6.8.0 a 6.8.11 | 6.8.12 |
| WordPress 6.7.x | 6.7.0 a 6.7.10 | 6.7.11 |
| WordPress 6.6.x | 6.6.0 a 6.6.10 | 6.6.11 |
| WordPress 6.5.x | 6.5.0 a 6.5.13 | 6.5.14 |
| WordPress 6.4.x | 6.4.0 a 6.4.13 | 6.4.14 |
| WordPress 6.3.x | 6.3.0 a 6.3.13 | 6.3.14 |
| WordPress 6.2.x | 6.2.0 a 6.2.14 | 6.2.15 |
| WordPress 6.1.x | 6.1.0 a 6.1.15 | 6.1.16 |
| WordPress 6.0.x | 6.0.0 a 6.0.17 | 6.0.18 |
| WordPress 5.9.x | 5.9.0 a 5.9.19 | 5.9.20 |
| WordPress 5.8.x | 5.8.0 a 5.8.18 | 5.8.19 |
| WordPress 5.7.x | 5.7.0 a 5.7.20 | 5.7.21 |
| WordPress 5.6.x | 5.6.0 a 5.6.22 | 5.6.23 |
| WordPress 5.5.x | 5.5.0 a 5.5.23 | 5.5.24 |
| WordPress 5.4.x | 5.4.0 a 5.4.24 | 5.4.25 |
| WordPress 5.3.x | 5.3.0 a 5.3.26 | 5.3.27 |
| WordPress 5.2.x | 5.2.0 a 5.2.29 | 5.2.30 |
| WordPress 5.1.x | 5.1.0 a 5.1.27 | 5.1.28 |
| WordPress 5.0.x | 5.0.0 a 5.0.30 | 5.0.31 |
| WordPress 4.9.x | 4.9.0 a 4.9.34 | 4.9.35 |
| WordPress 4.8.x | 4.8.0 a 4.8.33 | 4.8.34 |
| WordPress 4.7.x | 4.7.0 a 4.7.38 | 4.7.39 |
WordPress funciona en el 39,5 % de todos los sitios web. La encuesta de W3Techs del 31 de octubre muestra la distribución por versión principal, pero no distingue las publicaciones corregidas de las vulnerables. Use la tabla anterior para evaluar su sitio.
Compruebe la versión de cada sitio que ejecuta. Con la línea de comandos:
wp core version
Sin ella, lea la versión en el panel bajo Escritorio, luego Actualizaciones, o en el recuadro De un vistazo. Para inspeccionar la respuesta HTTP del directorio de descompresión, pídalo desde una máquina que controle, con su propio sitio:
curl -s -o /dev/null -w "%{http_code}\n" https://your-site.example/wp-content/upgrade/
La respuesta del directorio por sí sola no permite saber si los archivos PHP extraídos son accesibles. Un 200 puede corresponder a una página de índice; un 403 o 404 no demuestra que los archivos individuales estén bloqueados. Verifique la configuración del servidor e instale una versión corregida.
¿Cómo lo corrijo?
Actualice cada sitio a la versión corregida de su rama, o a 7.1.4:
- Haga una copia de seguridad del sitio y de su base de datos.
- Actualice desde el panel: Escritorio, Actualizaciones, Actualizar ahora. WordPress 7.1.4 es una publicación de seguridad, así que los sitios con actualizaciones automáticas en segundo plano la reciben automáticamente, como indica la nota de publicación.
- O actualice desde la línea de comandos:
wp core update
Como alternativa, para permanecer en la rama 7.0, use este comando en lugar del anterior:
wp core update --version=7.0.8
Use la versión corregida de su rama indicada en la tabla; no ejecute ambos comandos.
- Tras actualizar, borre cualquier resto bajo
wp-content/upgrade/que el actualizador no haya limpiado por sí mismo.
Para los sitios que aún no pueden actualizar, una solución temporal cierra la condición de accesibilidad web:
- Deniegue el acceso web al directorio de descompresión en el servidor web. Para nginx, dentro del bloque server:
location ^~ /wp-content/upgrade/ { return 403; }
- Para Apache, en la configuración del sitio o el
.htaccess:
RedirectMatch 403 ^/wp-content/upgrade/
La solución temporal cubre solo este CVE. Bloquea los archivos extraídos por el web, de modo que ni el instalador ni ningún otro archivo PHP extraído se ejecutan. No hace nada por ninguna otra falla, y debe permanecer hasta que el sitio alcance una versión corregida.
El archivo index.php que el WordPress corregido escribe en el directorio de actualización solo impide el listado del directorio. Las peticiones directas al nombre aleatorio del directorio de trabajo siguen funcionando, por lo que un bloqueo a nivel de servidor es más fuerte.
¿Cuál es la causa raíz?
El actualizador descomprime cada actualización del núcleo en un directorio de trabajo cuyo nombre se deriva solo del nombre de archivo del paquete, dentro de una carpeta que el servidor web sirve. En WordPress 7.1.3, WP_Upgrader::unpack_package() construye la ruta a partir del paquete sin nada impredecible, en wp-admin/includes/class-wp-upgrader.php línea 378:
$upgrade_folder = $wp_filesystem->wp_content_dir() . 'upgrade/';
// ...
// We need a working directory - strip off any .tmp or .zip suffixes.
$working_dir = $upgrade_folder . basename( basename( $package, '.tmp' ), '.zip' );
Un paquete de actualización del núcleo llamado wordpress-7.1.4.zip se descomprime por tanto en wp-content/upgrade/wordpress-7.1.4, una ruta que un atacante puede calcular antes de que empiece la actualización. El paquete contiene el árbol completo de WordPress, incluido wp-admin/setup-config.php, el asistente de instalación.
El asistente es la segunda mitad de la falla. setup-config.php se niega a ejecutarse solo cuando ya existe un archivo wp-config.php junto a él, en wp-admin/setup-config.php líneas 58 a 60:
// Check if wp-config.php has been created.
if ( file_exists( ABSPATH . 'wp-config.php' ) ) {
wp_die(
Un paquete de publicación incluye wp-config-sample.php, no wp-config.php, así que el árbol extraído nunca dispara esa comprobación. Una petición no autenticada al asistente extraído durante la ventana de actualización lo ejecuta. Escribe un wp-config.php en el árbol de descompresión a partir de los valores enviados del formulario: nombre de base de datos, usuario, contraseña, host y prefijo de tabla. WordPress 7.1.4 cambió los tres eslabones de esta cadena, como muestra la siguiente sección.
¿Cómo se explota?
El atacante sondea la ruta de descompresión predecible en busca del asistente extraído hasta que el sitio descomprime una actualización, gana la carrera de segundos y convierte el asistente extraído en ejecución de código. No hay código de prueba de concepto público, y Wordfence solo ha publicado los patrones de peticiones que bloqueó; los pasos provienen del código fuente afectado, de la corrección y de la descripción de Wordfence:
- El atacante calcula la ruta de descompresión para la versión que su objetivo está a punto de instalar, por ejemplo
/wp-content/upgrade/wordpress-7.1.4/, y la sondea en busca dewp-admin/setup-config.php. Wordfence vio dos fuentes sondear pequeños grupos de sitios durante unas 14.5 horas, y otras probaron muchas variantes de directorios y nombres de versiones. - Cuando el actualizador del sitio descomprime el paquete, los sondeos empiezan a alcanzar el asistente extraído. La ventana dura solo segundos en entornos de laboratorio, así que el ataque es un sondeo repetido, no una única petición manipulada.
- El asistente extraído se ejecuta, porque el árbol extraído no contiene ningún
wp-config.php. El atacante completa su formulario con ajustes de base de datos que apuntan a una base que controla, y el asistente escribe esos ajustes en unwp-config.phpdentro del árbol de descompresión. - El atacante luego interactúa con la copia extraída de WordPress contra su propia base de datos, como describe Wordfence. Mediante las pantallas de administración extraídas, que incluyen la subida de plugins y temas, progresa a la ejecución de PHP.
- Separadamente, antes de 7.1.4, el paso de copia de la actualización instalaba los archivos del directorio de trabajo en la raíz del sitio omitiendo solo
wp-contentywp-includes/version.php. Unwp-config.phpescrito por el atacante en el directorio de trabajo se copiaría por tanto a la raíz del sitio. Allí se ejecuta en cada petición y apunta el sitio real a la base de datos del atacante. - WordPress borra el directorio de trabajo tras la actualización, y la ventana se cierra. Un cambio de configuración que sobrevivió al paso 5 persiste; lo que quedó solo en el árbol de descompresión, no.
Las condiciones de éxito de Wordfence coinciden con estos pasos:
- una actualización de paquete completo que contiene los archivos del instalador
- acceso web y PHP público al árbol de descompresión
- una ruta de descompresión predecible o descubierta
- tiempo suficiente para completar el ataque antes de que WordPress limpie los archivos temporales
¿Cómo fluye el ataque?
Un atacante no autenticado sondea la ruta de descompresión predecible durante una actualización del sitio, alcanza el asistente extraído y lo convierte en ejecución de código antes de la limpieza. La comprobación ausente del flujo es la imprevisibilidad que el directorio de trabajo nunca tuvo.
wp-content/upgrade/wordpress-7.1.4"] B --> C["El atacante sondea el
setup-config.php extraído"] C --> D["El árbol extraído no tiene
wp-config.php: la comprobación pasa"] D --> E["El asistente escribe un wp-config.php
controlado por el atacante"] E --> F["La copia extraída funciona contra
la base del atacante"] F --> G["Subida de plugin por el admin
extraído: ejecución de PHP"] E --> H["comprobación ausente: la copia instala el
wp-config.php extraído en la raíz"] H --> I["El sitio real carga la
configuración del atacante"]
¿Qué puede hacer un atacante?
Un ganador de la carrera ejecuta código PHP en el servidor web, como el usuario del proceso de WordPress, durante la ventana de actualización. En las versiones anteriores a 7.1.4 también puede hacer persistente un cambio de configuración más allá de la ventana. El ataque no necesita cuenta, privilegios ni interacción de nadie en el sitio.
El equipo de seguridad de WordPress puntúa la falla Low y Wordfence la puntúa 8.1 High; la diferencia es la carrera, que el vector registra como complejidad de ataque High.
Lo que se sabe del uso real es más estrecho. Wordfence bloqueó 62,969 peticiones dirigidas a la falla en 24 horas al 30 de octubre de 2026, que son intentos, no compromisos. Ningún compromiso exitoso ha sido reportado por Wordfence, por la prensa ni por WordPress, y el CVE no está en el catálogo KEV al 31 de octubre de 2026.
La velocidad es la historia: los intentos de ataque masivos llegaron dos días después de publicarse la corrección, mientras los sitios aún pasaban a 7.1.4.
¿Por qué funciona la corrección?
WordPress 7.1.4 rompe la cadena en tres puntos en el commit b625b2d49c6a, «Upgrade/Install: Improve the handling of the upgrade working directory»:
$upgrade_folder = $wp_filesystem->wp_content_dir() . 'upgrade/';
- // Clean up contents of upgrade directory beforehand.
+ // Clean up contents of upgrade directory beforehand, keeping its index.php.
$upgrade_files = $wp_filesystem->dirlist( $upgrade_folder );
if ( ! empty( $upgrade_files ) ) {
foreach ( $upgrade_files as $file ) {
+ if ( 'index.php' === $file['name'] ) {
+ continue;
+ }
+
$wp_filesystem->delete( $upgrade_folder . $file['name'], true );
}
}
- // We need a working directory - strip off any .tmp or .zip suffixes.
- $working_dir = $upgrade_folder . basename( basename( $package, '.tmp' ), '.zip' );
+ /*
+ * The upgrade directory is web-served. Keep it from being listed, as core does
+ * for wp-content and its plugins and themes directories, so the name of the
+ * working directory created below cannot be discovered from a directory index.
+ */
+ if ( ! $wp_filesystem->exists( $upgrade_folder . 'index.php' ) ) {
+ $wp_filesystem->put_contents( $upgrade_folder . 'index.php', "<?php\n// Silence is golden.\n", FS_CHMOD_FILE );
+ }
+
+ // We need a working directory.
+ $working_dir = $upgrade_folder . $this->get_working_dir_name( $package );
El nuevo método privado añade un sufijo aleatorio:
private function get_working_dir_name( $package ) {
// Strip off any .tmp or .zip suffixes.
$name = basename( basename( $package, '.tmp' ), '.zip' );
return $name . '-' . wp_generate_password( 16, false );
}
El tercer cambio está en update-core.php, donde la lista de omisión del paso de copia gana el archivo que escribe el atacante:
- $skip = array( 'wp-content', 'wp-includes/version.php' );
+ $skip = array( 'wp-content', 'wp-includes/version.php', 'wp-config.php' );
El sufijo aleatorio elimina la ruta predecible, que ningún atacante puede calcular de antemano. El archivo index.php elimina el índice del directorio como forma de descubrir el nombre aleatorio. La entrada en la lista de omisión significa que incluso un atacante que encuentre el directorio ya no puede lograr que su wp-config.php se instale en la raíz del sitio.
La corrección es completa para esta cadena en el actualizador, y cada retroportado de rama lleva los tres mismos cambios. No elimina el acceso web al propio directorio de actualización. Por eso el bloqueo a nivel de servidor de «¿Cómo lo corrijo?» sigue siendo una defensa en profundidad valiosa.
¿Cómo compruebo si estuve comprometido?
Busque en los registros de acceso de su servidor web el patrón de peticiones de este ataque. En nginx, el registro por defecto consigna una línea por petición con la ruta:
# Nginx: requests to PHP files under the staging path, case-insensitive; decode encoded paths separately.
grep -iE "wp-content/upgrade/[^ ]+\.php" /var/log/nginx/access.log
En Apache, sustituya la ruta de su registro de acceso. Una ruta de descompresión en la petición, setup-config.php en particular, es el aspecto de esta falla:
# Apache: any request to the staged installer, on any version name.
grep -iE "wp-content/upgrade/.*/setup-config\.php" /var/log/apache2/access.log
Descodifique las rutas codificadas en porcentaje antes de juzgarlas, porque Wordfence informa de que los atacantes varían las grafías del directorio y de los nombres de versiones. Una petición legítima no tiene razón para llamar a estas rutas, así que cualquier incidencia amerita investigar la dirección de origen y lo que vino después; un único resultado es una pista, no una prueba. Luego busque lo que una carrera ganada deja atrás:
# Any PHP file left in the staging tree.
find wp-content/upgrade -name "*.php" | sort
Un único index.php que contiene // Silence is golden. es lo que el propio WordPress corregido escribe ahí. Cualquier otro archivo PHP, y en especial un wp-config.php, es una pista que investigar. Wordfence también aconseja buscar cuentas de administrador desconocidas, plugins que usted no instaló y archivos PHP que no reconoce. Un ataque fallido puede no dejar rastro más allá del propio sondeo.
Cronología
- 2026-10-28: WordPress publica 7.1.4 con el commit de corrección b625b2d49c6a, y retroporta la corrección a cada rama desde 7.0.8 hasta 4.7.39.
- 2026-10-29: WordPress publica su aviso GHSA-4w3m-c66w-69mg, que puntúa la condición de carrera Low, y acredita a Umut Bayram de Picus Security.
- 2026-10-30: The Hacker News informa del recuento de Wordfence de 62,969 ataques bloqueados en 24 horas; no se reporta ningún compromiso.
- 2026-10-31: el registro CVE-2026-119977 se publica por Wordfence con una puntuación CVSS v3.1 de 8.1 High. La falla no está en el catálogo KEV de CISA a esta fecha.
Preguntas frecuentes
¿Actualizarme a 7.1.4 me expone durante esa misma actualización?
Sí, durante los segundos que dura la actualización. El código que ejecuta una actualización es la versión instalada antes de ella, así que la actualización a 7.1.4 todavía descomprime en una ruta predecible. Un ataque en ese momento requiere un atacante que ya esté sondeando su sitio, que es lo que Wordfence observó. Actualice de inmediato en lugar de esperar, y mantenga el bloqueo a nivel de servidor de «¿Cómo lo corrijo?» durante la ventana de cambio.
Mi sitio ejecuta una rama antigua. ¿Tengo que saltar a 7.1.4?
No. WordPress retroportó la corrección a cada rama hasta 4.7, así que 7.0.8, 6.9.11 y todos los demás retroportados de la tabla de ramas de «¿Estoy afectado?» llevan los tres mismos cambios. Saltar de rama conlleva su propio riesgo de compatibilidad, así que el retroportado de su rama es el cambio más pequeño.
¿Por qué WordPress y Wordfence difieren en la gravedad?
WordPress puntúa la condición de carrera subyacente Low, y el registro CVE de Wordfence la puntúa 8.1 High con complejidad de ataque High. Ambos describen el mismo camino no autenticado hacia la ejecución de código; la puntuación Low pondera la ventana de segundos, y la High el impacto de ganarla. En cualquier caso, la corrección es la misma y la telemetría de ataque es real.
¿Qué observó exactamente Wordfence?
Wordfence bloqueó 62,969 peticiones dirigidas a esta falla en 24 horas al 30 de octubre de 2026. Dos de las fuentes más grandes sondearon pequeños grupos de sitios durante unas 14.5 horas, y otras fuentes probaron muchas variantes de directorios y nombres de versiones. Son intentos que un producto cortafuegos bloqueó, no compromisos confirmados, y no se ha reportado ninguna víctima.
¿Bastan las actualizaciones automáticas?
Son el mecanismo de entrega de la corrección, y la nota de publicación confirma que las publicaciones de seguridad se actualizan automáticamente donde se admiten las actualizaciones en segundo plano. La exposición que dejan es la propia ventana de actualización. Combínelas con las comprobaciones de registros de este artículo tras la actualización, y con el bloqueo a nivel de servidor si el directorio de descompresión es accesible por el web.
Encuentre sus despliegues de WordPress antes de que los atacantes los sondeen
El escaneo agéntico web de Ostorlab inventaría sus aplicaciones web y sus versiones de frameworks. Muestra cuáles de sus sitios ejecutan WordPress 4.7.0 a 7.1.3, para que pueda llevarlos a una versión corregida antes de que se abra la próxima ventana de actualización.
Referencias
- Aviso de seguridad de WordPress GHSA-4w3m-c66w-69mg, «A race condition during core updates that could lead to remote code execution», publicado el 29 de octubre de 2026, con la matriz de versiones corregidas por rama: https://github.com/WordPress/wordpress-develop/security/advisories/GHSA-4w3m-c66w-69mg (consultado el 31 de octubre de 2026)
- Registro CVE-2026-119977, publicado por el CNA Wordfence con CVSS v3.1 8.1: https://www.cve.org/CVERecord?id=CVE-2026-119977 (consultado el 31 de octubre de 2026)
- Nota de publicación de WordPress 7.1.4, 28 de octubre de 2026, que acredita a Umut Bayram por el informe del proceso de actualización: https://wordpress.org/news/2026/10/wordpress-7-1-4/ (consultado el 31 de octubre de 2026)
- Commit de corrección b625b2d49c6a, «Upgrade/Install: Improve the handling of the upgrade working directory», en WordPress 7.1.4: https://github.com/WordPress/WordPress/commit/b625b2d49c6a (consultado el 31 de octubre de 2026)
- Código fuente de WordPress 7.1.3, derivación del directorio de trabajo vulnerable en
WP_Upgrader::unpack_package()y comprobación desetup-config.phpsobre la configuración existente: https://raw.githubusercontent.com/WordPress/WordPress/7.1.3/wp-admin/includes/class-wp-upgrader.php y https://raw.githubusercontent.com/WordPress/WordPress/7.1.3/wp-admin/setup-config.php (consultado el 31 de octubre de 2026) - Análisis de Wordfence de la publicación de seguridad 7.1.4, «WordPress 7.1.4 Patches Unauthenticated Upgrade-Window RCE; Exploitation Attempts Detected After Release», 29 de octubre de 2026: https://www.wordfence.com/blog/2026/10/wordpress-7-1-4-security-release-rce/ (consultado el 31 de octubre de 2026)
- The Hacker News, «WordPress RCE Flaw Draws Nearly 63,000 Attack Attempts in Just 24 Hours», 30 de octubre de 2026, citando a Alex Thomas de Wordfence y los 62,969 ataques bloqueados: https://thehackernews.com/2026/10/wordpress-rce-flaw-draws-nearly-63000.html (consultado el 31 de octubre de 2026)
- Ficha de inteligencia de amenazas de Wordfence para la RCE de ventana de actualización de WordPress Core 4.7-7.1.3: https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-core/wordpress-core-470-713-unauthenticated-upgrade-window-staged-installer-remote-code-execution (consultado el 31 de octubre de 2026)
- Catálogo Known Exploited Vulnerabilities de CISA, fuente JSON, buscado para CVE-2026-119977: https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json (consultado el 31 de octubre de 2026)
- Estadísticas de uso de W3Techs para WordPress, 39.5% de todos los sitios web y la distribución por versiones: https://w3techs.com/technologies/details/cm-wordpress (consultado el 31 de octubre de 2026)