问题描述 / Problem Description
在 openai_routes.py 的 _get_file_path 函数逻辑中存在路径穿越风险。函数对用户传入的 file_id 进行 Base64 解码后,未进行任何路径合法性校验(如过滤 / 或 ..),直接传递给 os.path.join 拼接。由于 Python os.path.join 的机制,当遇到绝对路径时会直接丢弃前缀目录。攻击者可利用此特性构造包含绝对路径的恶意 file_id,绕过目录限制。
复现问题的步骤 / Steps to Reproduce
-
审计 openai_routes.py 中的 _get_file_path 函数代码逻辑。
-
构造 Payload:将目标文件的绝对路径(例如 /etc/passwd)进行 Base64 URL 编码,生成恶意 file_id(如 L2V0Yy9wYXNzd2Q=)。
-
理论触发读取:调用 GET /v1/files/{Payload}/content,os.path.join 会直接返回 /etc/passwd,并由 FileResponse 读取该文件。
-
理论触发删除:调用 DELETE /v1/files/{Payload},将直接触发 os.remove('/etc/passwd')。
预期的结果 / Expected Result
程序应对 Base64 解码后的 file_id 字符串进行严格的安全清洗与校验。例如,拒绝任何包含路径分隔符(/ 或 \)及相对路径符号(..)的输入,确保最终拼接出的文件路径严格被限制在 Settings.basic_settings.BASE_TEMP_DIR/openai_files 目录层级之内。
实际结果 / Actual Result
由于缺乏路径规范化处理,安全边界失效。攻击者可以通过 API 越权访问或恶意删除宿主机操作系统上的任意敏感文件。
问题描述 / Problem Description
在 openai_routes.py 的 _get_file_path 函数逻辑中存在路径穿越风险。函数对用户传入的 file_id 进行 Base64 解码后,未进行任何路径合法性校验(如过滤 / 或 ..),直接传递给 os.path.join 拼接。由于 Python os.path.join 的机制,当遇到绝对路径时会直接丢弃前缀目录。攻击者可利用此特性构造包含绝对路径的恶意 file_id,绕过目录限制。
复现问题的步骤 / Steps to Reproduce
审计 openai_routes.py 中的 _get_file_path 函数代码逻辑。
构造 Payload:将目标文件的绝对路径(例如 /etc/passwd)进行 Base64 URL 编码,生成恶意 file_id(如 L2V0Yy9wYXNzd2Q=)。
理论触发读取:调用 GET /v1/files/{Payload}/content,os.path.join 会直接返回 /etc/passwd,并由 FileResponse 读取该文件。
理论触发删除:调用 DELETE /v1/files/{Payload},将直接触发 os.remove('/etc/passwd')。
预期的结果 / Expected Result
程序应对 Base64 解码后的 file_id 字符串进行严格的安全清洗与校验。例如,拒绝任何包含路径分隔符(/ 或 \)及相对路径符号(..)的输入,确保最终拼接出的文件路径严格被限制在 Settings.basic_settings.BASE_TEMP_DIR/openai_files 目录层级之内。
实际结果 / Actual Result
由于缺乏路径规范化处理,安全边界失效。攻击者可以通过 API 越权访问或恶意删除宿主机操作系统上的任意敏感文件。