
Laboratorio basado en Docker para reproducir CVE-2026-49060, una escalada de privilegios no autenticada en el plugin Hippoo Mobile App para WooCommerce de WordPress. Compara las versiones vulnerable 1.9.4 y parcheada 1.9.5 con un PoC en Python.
Este repositorio contiene un laboratorio Docker local para reproducir y validar CVE-2026-49060, una vulnerabilidad de Asignación Incorrecta de Privilegios que afecta al plugin de WordPress Aplicación Móvil Hippoo para WooCommerce.
El comportamiento vulnerable se expone a través del espacio de nombres de la API REST clonada de Hippoo:```text /wc-hippoo/v1/ext/
En el objetivo vulnerable, un visitante no autenticado puede acceder a una ruta clonada de usuarios de la REST API de WordPress y puede actualizar la contraseña del usuario administrador mediante una solicitud HTTP no autenticada. En el objetivo parcheado, la misma solicitud es bloqueada con `403 Forbidden`.
Este laboratorio compara dos versiones de Hippoo:
| Service | Hippoo version | Purpose | URL |
| --------- | -------------: | ---------------------------- | ----------------------- |
| `vuln` | 1.9.4 | Objetivo de comparación vulnerable | `http://localhost:8081` |
| `patched` | 1.9.5 | Objetivo de comparación parcheado | `http://localhost:8082` |
La cadena de vulnerabilidad demostrada es:
-```text
Unauthenticated visitor
→ Hippoo cloned REST namespace
→ /wc-hippoo/v1/ext/wp/v2/users/<id>
→ vulnerable permission handling allows access
→ unauthenticated GET exposes user data
→ unauthenticated POST can update the selected user's password
→ patched version blocks the same request with 403 Forbidden
Este laboratorio valida el comportamiento de autorización vulnerable versus parcheado utilizando Hippoo 1.9.4 y Hippoo 1.9.5.
El laboratorio está intencionalmente limitado a servicios Docker locales. No tiene como objetivo sistemas externos y no incluye persistencia, webshells, malware ni devoluciones de llamada externas.
| Afirmación | Evidencia | Cómo verificar en este laboratorio |
|---|---|---|
CVE-2026-49060 afecta a Hippoo Mobile App para WooCommerce hasta la versión 1.9.4. | Los avisos públicos identifican a Hippoo <= 1.9.4 / hasta 1.9.4 como afectado. | Revise la sección de Referencias y compare la versión del servicio vuln. |
Hippoo 1.9.5 se utiliza como objetivo de comparación parcheado. | Los metadatos de avisos públicos identifican 1.9.5 como una versión parcheada para el rango afectado. | Ejecute docker compose logs init-vuln init-patched y confirme las versiones de los plugins inicializados. |
| El comportamiento vulnerable se expone a través del espacio de nombres REST clonado de Hippoo. | Hippoo vuelve a registrar rutas REST externas bajo /wc-hippoo/v1/ext/. | Ejecute python3 poc/poc.py http://127.0.0.1:8081 http://127.0.0.1:8082. |
Hippoo 1.9.4 permite acceso no autenticado a la ruta de usuarios clonada en este laboratorio. | El PoC del laboratorio recibe 200 OK desde http://127.0.0.1:8081/?rest_route=/wc-hippoo/v1/ext/wp/v2/users/1. | Ejecute el comando de validación de solo lectura contra 8081. |
Hippoo 1.9.5 bloquea la misma solicitud no autenticada en este laboratorio. | El PoC del laboratorio recibe 403 Forbidden desde http://127.0.0.1:8082/?rest_route=/wc-hippoo/v1/ext/wp/v2/users/1. | Ejecute el comando de validación de solo lectura contra 8082. |
| El objetivo vulnerable puede actualizar la contraseña del administrador a través de un POST no autenticado en este laboratorio local. | El PoC activo recibe 200 OK del objetivo vulnerable cuando se usa --update-password. | Ejecute python3 poc/poc.py --update-password http://127.0.0.1:8081. |
| El objetivo parcheado bloquea la solicitud de actualización de contraseña no autenticada. | Hippoo 1.9.5 devuelve una respuesta de prohibido para la misma ruta de usuarios clonada. | Ejecute validación activa contra ambos objetivos. |
| El PoC es solo HTTP. | poc/poc.py envía solo solicitudes HTTP y no llama a Docker, WP-CLI ni APIs de contenedores. | Inspeccione poc/poc.py. |
Este laboratorio utiliza Hippoo 1.9.4 como objetivo de comparación vulnerable porque los avisos públicos identifican las versiones hasta 1.9.4 como afectadas.
Este laboratorio utiliza Hippoo 1.9.5 como objetivo de comparación parcheado porque los metadatos de avisos públicos identifican 1.9.5 como la versión corregida para el rango afectado demostrado.
El registro público de CVE-2026-49060 describe el problema a alto nivel como Asignación Incorrecta de Privilegios / Escalada de Privilegios. Este laboratorio se centra en el comportamiento observable de autorización en Hippoo 1.9.4 y lo compara con Hippoo 1.9.5.
El resumen de la causa raíz en este README se basa en la comparación de fuentes entre las versiones vulnerable y parcheada de Hippoo utilizadas en el laboratorio.
Este laboratorio no pretende probar todas las rutas de Hippoo. Se centra en la ruta REST clonada de usuarios de WordPress:```text /wc-hippoo/v1/ext/wp/v2/users/
El laboratorio no demuestra:
* persistencia,
* carga de web shell,
* ejecución de comandos arbitrarios,
* callbacks externos,
* comportamiento de malware,
* ataques contra sistemas que no son del laboratorio,
* o actividad posterior al compromiso más allá de la validación local de actualización de contraseña.
## Resumen de la causa raíz
La causa raíz es un error de lógica de permisos en el manejo de roles y permisos de Hippoo.
Hippoo expone rutas REST clonadas de WordPress y WooCommerce bajo su propio espacio de nombres:```text
/wc-hippoo/v1/ext/
El comportamiento de clonación de rutas es sensible a la seguridad porque la ruta clonada debe preservar o fortalecer los requisitos de autorización de la ruta original. Si la ruta clonada recibe una devolución de llamada de permiso permisiva, los usuarios no autenticados podrían acceder a endpoints REST que deberían requerir autenticación y autorización.
El comportamiento relevante de clonación de rutas sigue este patrón:```php function re_register_external_routes() { $server = rest_get_server(); $endpoints = $server->get_routes();
$new_namespace = $this->hippoo_namespace . '/ext';
foreach ($endpoints as $route => $handlers) {
if (strpos($route, $this->hippoo_namespace) === 0) {
continue;
}
foreach ($handlers as $handler) {
$default_permission_callback = array($this, 'is_user_wordpress_admin');
$permission_callback = apply_filters(
'hippoo_extension_permission_check',
$default_permission_callback,
$route,
$handler
);