Ir al contenido principal
Seguridad & Backend · 6 min

Vulnerabilidad crítica en WordPress Core (CVE-2026-87902): Path Traversal no autenticado y RCE condicional

Análisis técnico del aviso GHSA-7hp8-65ch-5whp en WordPress Core (4.7 a 7.1.1): cómo la resolución de plantillas permite inclusión de archivos locales, qué condiciones desencadenan RCE y cómo mitigarlo.

Pablo Fesa
Pablo Fesa Software Architect & Tech Lead

El equipo de seguridad de WordPress Core ha publicado un aviso de seguridad de gravedad crítica identificado como GHSA-7hp8-65ch-5whp (registrado como CVE-2026-87902 y con una puntuación CVSS v4.0 de 9.2).

El boletín, publicado por John Blackbourn (johnbillion, desarrollador principal y miembro del equipo de seguridad de WordPress) a raíz del reporte responsable del investigador Robert Ressl, afecta a todas las versiones de WordPress Core desde la 4.7.0 hasta la 7.1.1. Prácticamente una década completa de versiones del CMS más extendido de internet comparte esta debilidad en su motor de renderizado de plantillas.

A continuación analizamos la anatomía técnica del fallo, por qué la ejecución remota de código (RCE) está catalogada como condicional y qué medidas inmediatas deben aplicar los administradores de sistemas y equipos de backend.


¿En qué consiste el fallo?

La vulnerabilidad reside en la lógica de resolución de plantillas de página dentro del core de WordPress, concretamente en la función get_page_template() ubicada en wp-includes/template.php.

En el ciclo de vida habitual de una petición web, WordPress determina qué archivo PHP del tema activo debe encargarse de renderizar la página consultada. Para ello, evalúa la jerarquía de plantillas y los metadatos asignados a la página (como el metadato _wp_page_template):

[Petición HTTP entrante]
          │
          ▼
[WP Query: Parseo de URL y Template Hierarchy]
          │
          ▼
[get_page_template() en wp-includes/template.php]
          │  (Sin validación canónica estricta)
          ▼
[Inclusión mediante include / locate_template()]

El defecto radica en una validación deficiente de la ruta del archivo de plantilla. Al no restringir de forma canónica que el archivo resultante resida obligatoriamente dentro del directorio del tema activo, un atacante remoto no autenticado puede inyectar secuencias de salto de directorio (como ../ o su codificación en URL %2e%2e%2f).

Esto convierte el mecanismo de resolución en una vulnerabilidad de Inclusión Local de Archivos (LFI - Local File Inclusion) sin necesidad de credenciales ni interacción de ningún usuario.


Impacto inmediato: lectura y ejecución de archivos locales (LFI)

A través de esta brecha, un atacante no autenticado puede forzar al intérprete de PHP a incluir y ejecutar cualquier archivo con extensión .php legible por el usuario del servidor web (www-data o equivalente).

El objetivo primario en cualquier instalación comprometida suele ser wp-config.php:

  • Exposición de credenciales de base de datos: usuario, contraseña, host y prefijo de tablas MySQL.
  • Filtración de claves y sales de seguridad: AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY, lo que permite forjar cookies de sesión legítimas y tomar el control administrativo del sitio.

¿Por qué la Ejecución Remota de Código (RCE) es “condicional”?

El aviso de seguridad califica el impacto como Conditional RCE. Para que un atacante consiga saltar de la inclusión de archivos locales a la ejecución arbitraria de comandos en el sistema operativo, deben cumplirse dos condiciones técnicas en el entorno:

1. Estructura de directorios del tema activo

El tema activo (o su tema hijo / child theme) debe contener un directorio en su raíz cuyo nombre comience por page- (por ejemplo, el directorio estándar page-templates/).

Esta estructura es extremadamente común en el ecosistema. Temas por defecto históricos de WordPress como Twenty Twelve y Twenty Fourteen, así como temas comerciales y comunitarios con millones de instalaciones como Neve, Hestia o Sydney, cumplen exactamente este requisito estructural.

2. Configuración del runtime de PHP (register_argc_argv = On)

La directiva de PHP register_argc_argv determina si los parámetros pasados en la cadena de consulta de la URL (query string) se registran en el array global $_SERVER['argv'] como si se tratara de una invocación por línea de comandos (CLI).

Cuando esta directiva se encuentra activa (On en php.ini), un atacante puede abusar de la combinación de la inclusión de plantillas y la inyección de argumentos para manipular el comportamiento interno de librerías en memoria o forzar la interpretación de código inyectado.

Aunque en configuraciones modernas de producción register_argc_argv suele estar desactivada para servidores web, sigue activa por defecto en:

  • Múltiples imágenes base oficiales de Docker y contenedores de desarrollo que pasaron a producción sin hardening.
  • Servidores con configuraciones heredadas de PHP-CGI.
  • Proveedores de hosting compartido donde la configuración global no fue endurecida.

La solución oficial: WordPress 7.1.2

El 22 de septiembre de 2026, el equipo de WordPress publicó la versión 7.1.2 resolviendo esta vulnerabilidad. Adicionalmente, aplicó parches de seguridad retroactivos (backports) a todas las ramas mantenidas desde la versión 4.7 (hasta la versión 4.7.37).

El parche introduce una verificación estricta sobre las rutas devueltas:

  1. Normalización canónica de la ruta con comprobación frente a la raíz del tema activo (get_stylesheet_directory() y get_template_directory()).
  2. Descarte inmediato de cualquier valor que contenga secuencias de escape de directorio o que resuelva fuera de los directorios autorizados de plantillas.

Plan de acción recomendado para ingenieros y administradores

Si administras servidores, clusters o plataformas que ejecutan instancias de WordPress, aplica las siguientes medidas de inmediato:

1. Actualización inmediata del Core

Actualiza a la versión 7.1.2 o, si tu plataforma depende de una rama menor específica, aplica la última versión de mantenimiento de dicha rama:

# Comprobar versión actual mediante WP-CLI
wp core check-update

# Actualizar el core manteniendo la estabilidad
wp core update

2. Endurecimiento de la directiva en php.ini

Verifica en todos tus servidores y pools de PHP-FPM que register_argc_argv esté explícitamente deshabilitado:

; /etc/php/8.x/fpm/php.ini
register_argc_argv = Off

Reinicia el servicio PHP-FPM tras aplicar el cambio:

sudo systemctl restart php8.x-fpm

3. Reglas de mitigación en WAF y Nginx

Si tienes sitios que no pueden actualizarse de inmediato por dependencias legacy, bloquea en el proxy inverso o WAF cualquier petición que intente inyectar secuencias de navegación de directorios en parámetros de consulta:

# Regla en bloque server de Nginx
if ($query_string ~* "(\.\./|\.\.\\|%2e%2e%2f|%2e%2e/)") {
    return 403;
}

4. Permisos mínimos y aislamiento de archivos

  • Asegura que wp-config.php tenga permisos de solo lectura estricta (chmod 400 o chmod 440) y pertenezca al usuario del servidor web sin privilegios.
  • Utiliza directivas open_basedir para impedir que el intérprete de PHP pueda leer archivos del sistema operativo fuera del directorio raíz asignado a la web.

Conclusión de ingeniería

El caso de CVE-2026-87902 ilustra un principio fundamental de la seguridad en sistemas: las vulnerabilidades críticas no siempre requieren código nuevo ni exploits sofisticados; a menudo viven latentes durante años en funciones fundamentales de resolución de recursos.

La mejor defensa para plataformas críticas nunca es confiar en que el framework esté libre de fallos, sino aplicar una estrategia de defensa en profundidad donde el runtime de PHP, el cortafuegos perimetral y los permisos del sistema operativo limiten el radio de impacto de cualquier inclusión no prevista.

Temas: #WordPress #Seguridad #PHP #Vulnerabilidades #DevOps
Sigue leyendo

Artículos Relacionados

¿Necesitas diseñar sistemas resistentes sin sobrecostes de infraestructura?

Hablemos 15 minutos en una sesión de diagnóstico técnico con Pablo para auditar tus cuellos de botella y definir la arquitectura adecuada.