
本仓库提供了一个本地 Docker 实验室环境,用于复现和验证 CVE-2026-49060,这是一个影响 WordPress 插件 Hippoo Mobile App for WooCommerce 的权限分配错误漏洞。
该漏洞行为通过 Hippoo 克隆的 REST API 命名空间暴露:```text /wc-hippoo/v1/ext/
在易受攻击的目标中,未认证的访问者可以访问克隆的WordPress REST用户路由,并通过未认证的HTTP请求更新管理员用户的密码。在已修补的目标中,相同的请求会返回 `403 Forbidden`。
本实验比较两个Hippoo版本:
| 服务 | Hippoo 版本 | 用途 | URL |
| ---------- | ----------: | ------------------------- | ----------------------- |
| `vuln` | 1.9.4 | 易受攻击的比较目标 | `http://localhost:8081` |
| `patched` | 1.9.5 | 已修补的比较目标 | `http://localhost:8082` |
展示的漏洞链为:```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
本实验室使用 Hippoo 1.9.4 和 Hippoo 1.9.5 来验证易受攻击与已修补的授权行为。
本实验室的范围明确限定为本地 Docker 服务。它不以外部系统为目标,也不包含持久化、Web Shell、恶意软件或外部回调。
| 声明 | 证据 | 如何在本实验室中验证 |
|---|---|---|
CVE-2026-49060 影响 WooCommerce 的 Hippoo 移动应用,直至版本 1.9.4。 | 公开公告指出 Hippoo <= 1.9.4 / 至 1.9.4 版本受影响。 | 查阅参考资料部分,并比较 vuln 服务的版本。 |
Hippoo 1.9.5 被用作已修补的比较目标。 | 公开公告的元数据将 1.9.5 标识为受影响范围内的已修补版本。 | 运行 docker compose logs init-vuln init-patched 并确认初始化的插件版本。 |
| 易受攻击的行为通过 Hippoo 克隆的 REST 命名空间暴露。 | Hippoo 在 /wc-hippoo/v1/ext/ 下重新注册外部 REST 路由。 | 运行 python3 poc/poc.py http://127.0.0.1:8081 http://127.0.0.1:8082。 |
在本实验室中,Hippoo 1.9.4 允许未经过身份验证访问克隆的用户路由。 | 实验室 PoC 从 http://127.0.0.1:8081/?rest_route=/wc-hippoo/v1/ext/wp/v2/users/1 收到 200 OK。 | 针对 8081 运行只读验证命令。 |
在本实验室中,Hippoo 1.9.5 阻止相同的未经过身份验证的请求。 | 实验室 PoC 从 http://127.0.0.1:8082/?rest_route=/wc-hippoo/v1/ext/wp/v2/users/1 收到 403 Forbidden。 | 针对 8082 运行只读验证命令。 |
| 在本本地实验室中,易受攻击的目标可以通过未经过身份验证的 POST 更新管理员密码。 | 当使用 --update-password 时,活动 PoC 从易受攻击的目标收到 200 OK。 | 运行 python3 poc/poc.py --update-password http://127.0.0.1:8081。 |
| 已修补的目标阻止未经过身份验证的密码更新请求。 | Hippoo 1.9.5 对相同的克隆用户路由返回禁止响应。 | 对两个目标运行活动验证。 |
| PoC 仅使用 HTTP。 | poc/poc.py 仅发送 HTTP 请求,不调用 Docker、WP-CLI 或容器 API。 | 检查 poc/poc.py。 |
本实验室使用 Hippoo 1.9.4 作为易受攻击的比较目标,因为公开公告指出直至 1.9.4 版本受影响。
本实验室使用 Hippoo 1.9.5 作为已修补的比较目标,因为公开公告的元数据将 1.9.5 标识为所演示受影响范围的已修复版本。
公开的 CVE-2026-49060 记录将问题描述为高层次的“不正确的权限分配/权限提升”。本实验室侧重于观察 Hippoo 1.9.4 中的授权行为,并与 Hippoo 1.9.5 进行比较。
本 README 中的根本原因总结基于本实验室中使用的易受攻击和已修补 Hippoo 版本的源代码比较。
本实验室并未声称测试了所有 Hippoo 路由。它专注于克隆的 WordPress 用户 REST 路由:```text /wc-hippoo/v1/ext/wp/v2/users/
实验室不演示:
* 持久性,
* Web Shell 上传,
* 任意命令执行,
* 外部回调,
* 恶意软件行为,
* 对非实验系统的攻击,
* 或超出本地密码更新验证的入侵后活动。
## 根本原因总结
根本原因是 Hippoo 角色和权限处理中的权限逻辑缺陷。
Hippoo 在其自己的命名空间下暴露了克隆的 WordPress 和 WooCommerce REST 路由:```text
/wc-hippoo/v1/ext/
路由克隆行为对安全性敏感,因为克隆后的路由必须保留或加强原始路由的授权要求。如果克隆后的路由接收了一个宽松的权限回调,未经身份验证的用户可能能够访问本应要求身份验证和授权的REST端点。
相关的路由克隆行为遵循以下模式:```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
);
register_rest_route(
$new_namespace,
$route,
array(
'methods' => $methods,
'callback' => $handler['callback'],
'args' => $handler['args'],
'permission_callback' => $permission_callback,
)
);
}
}
}
预期的安全模型是:```text
Original protected REST route
→ cloned into Hippoo namespace
→ permission callback still denies unauthenticated access
这种易受攻击的行为是因为 Hippoo 1.9.4 对两种不同的状态使用了相同的返回值:```text
administrator / unrestricted access
unauthenticated visitor / no user
在 Hippoo `1.9.4` 中,当没有已登录的 WordPress 用户时,权限助手返回 `null`:```php
public static function get_user_permissions()
{
$user = wp_get_current_user();
if (empty($user) || !$user->exists()) {
return null;
}
if (in_array('administrator', (array) $user->roles)) {
return null; // Full access
}
$settings = get_option('hippoo_permissions_settings', []);
foreach ((array) $user->roles as $role) {
if (!isset($settings[$role])) {
continue;
}
return $settings[$role];
}
return null; // Full access
}
易受攻击的版本同样将 null 视为允许的:```php
private function has_role_access($section, $key = null)
{
$perms = self::get_user_permissions();
if ($perms === null) {
return true; // admin or unrestricted
}
if (empty($perms['general']['enable_access'])) {
return false;
}
}
这创建了有漏洞的数据流:```text
Unauthenticated visitor
→ no WordPress user exists
→ get_user_permissions() returns null
→ has_role_access() treats null as allowed
→ cloned REST route permission can become permissive
→ unauthenticated request reaches sensitive REST endpoints
问题不仅仅在于存在一个REST路由。问题在于权限决策可能会错误地将未经身份验证的访客视为不受限制。
修复版本将这些状态分离开来。
在 Hippoo 1.9.5 中,未经身份验证的访客返回 false 而非 null:```php
public static function get_user_permissions()
{
$user = wp_get_current_user();
if (empty($user) || !$user->exists() || !is_user_logged_in()) {
return false;
}
if (in_array('administrator', (array) $user->roles)) {
return null; // Full access
}
$settings = get_option('hippoo_permissions_settings', []);
foreach ((array) $user->roles as $role) {
if (isset($settings[$role])) {
return $settings[$role];
}
}