Skip to content

[BUG] openai_routes.py 存在路径穿越导致任意文件读取与删除漏洞 (基于代码静态分析) / Path Traversal leading to Arbitrary File Read/Delete in openai_routes.py (Static Analysis) #5482

Description

@QiuYucheng2003

问题描述 / Problem Description
在 openai_routes.py 的 _get_file_path 函数逻辑中存在路径穿越风险。函数对用户传入的 file_id 进行 Base64 解码后,未进行任何路径合法性校验(如过滤 / 或 ..),直接传递给 os.path.join 拼接。由于 Python os.path.join 的机制,当遇到绝对路径时会直接丢弃前缀目录。攻击者可利用此特性构造包含绝对路径的恶意 file_id,绕过目录限制。

复现问题的步骤 / Steps to Reproduce

  1. 审计 openai_routes.py 中的 _get_file_path 函数代码逻辑。

  2. 构造 Payload:将目标文件的绝对路径(例如 /etc/passwd)进行 Base64 URL 编码,生成恶意 file_id(如 L2V0Yy9wYXNzd2Q=)。

  3. 理论触发读取:调用 GET /v1/files/{Payload}/content,os.path.join 会直接返回 /etc/passwd,并由 FileResponse 读取该文件。

  4. 理论触发删除:调用 DELETE /v1/files/{Payload},将直接触发 os.remove('/etc/passwd')。

预期的结果 / Expected Result
程序应对 Base64 解码后的 file_id 字符串进行严格的安全清洗与校验。例如,拒绝任何包含路径分隔符(/ 或 \)及相对路径符号(..)的输入,确保最终拼接出的文件路径严格被限制在 Settings.basic_settings.BASE_TEMP_DIR/openai_files 目录层级之内。

实际结果 / Actual Result
由于缺乏路径规范化处理,安全边界失效。攻击者可以通过 API 越权访问或恶意删除宿主机操作系统上的任意敏感文件。

Activity

  1. dosubot commented on Jun 9, 2026

    @dosubot

    This vulnerability has already been reported in detail in issue #5474 [1], which covers the same path traversal in _get_file_path (arbitrary file read/delete) along with additional findings (arbitrary file write via upload filename and missing authentication on all endpoints).

    Your analysis is correct. The vulnerable code at lines 255-257 of openai_routes.py [2]:

    def _get_file_path(file_id: str) -> str:
        file_id = base64.urlsafe_b64decode(file_id).decode()
        return os.path.join(Settings.basic_settings.BASE_TEMP_DIR, "openai_files", file_id)

    performs no sanitization — no filtering of ../, no rejection of absolute paths, and no os.path.realpath() + prefix validation. As you noted, Python's os.path.join discards all preceding components when it encounters an absolute path segment, making the BASE_TEMP_DIR restriction trivially bypassable.

    The recommended fix (as also suggested in #5474) would be to resolve the final path with os.path.realpath() and then verify it starts with the expected base directory prefix before proceeding with any file operation.

    To reply, just mention @dosu.


    Share context across your team and agents. Try Dosu.

    Leave Feedback Learn about Langchain-Chatchat with Dosu Add Dosu to your team

  2. github-actions commented on Jul 9, 2026

    @github-actions

    这个问题已经被标记为 stale ,因为它已经超过 30 天没有任何活动。

  3. github-actions commented on Jul 24, 2026

    @github-actions

    这个问题已经被自动关闭,因为它被标为 stale 后超过 14 天没有任何活动。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingstale

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions