Flask send_file函数如何避免绝对路径长尾词遍历?

2026-04-11 04:322阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1302个文字,预计阅读时间需要6分钟。

Flask send_file函数如何避免绝对路径长尾词遍历?

平时接触到的Python项目并不多,对Python的代码审查更是没有接触。偶然间朋友发现了一个漏洞——Flask的send_file函数导致的绝对路径遍历,感觉打开了新世界的大门,即便是初学者也跃跃欲试。

平时接触到的 python 项目并不多,对 python 的代码审计更是没有接触,偶然朋友发来了一个漏洞 Flask send_file函数导致的绝对路径遍历 ,感觉打开了新世界的大门,于是就以一个初学者的角度,进行复现分析一下。

  平时接触到的 python 项目并不多,对 python 的代码审计更是没有接触,偶然朋友发来了一个漏洞Flask send_file函数导致的绝对路径遍历,感觉打开了新世界的大门,于是就以一个初学者的角度,进行复现分析一下。详情也可以根据Python : Flask Path Traversal Vulnerability进行分析学习

send_file 的妙用

  在以 flask 框架开发的系统中,为了直接实现用户访问某一个 URL 时就可以下载到文件,我们就使用send_file来实现

from flask import Flask
from flask import send_file

app = Flask(__name__)


@app.route('/download')
def downloadFile():
path = "test.txt"
return send_file(path)


if __name__ == '__main__':
app.run()

  我们看到 如此运行的效果是直接返回了文件的内容,浏览器并没有识别成一个文件下载下来。

  要想让浏览器识别成为文件下载的话,只需要加上as_attachment=True

from flask import Flask
from flask import send_file

app = Flask(__name__)


@app.route('/download')
def downloadFile():
path = "test.txt"
return send_file(path, as_attachment=True)


if __name__ == '__main__':
app.run()

  

  

  当下载的文件名是中文时

from flask import Flask
from flask import send_file

app = Flask(__name__)


@app.route('/download')
def downloadFile():
path = "测试.txt"
return send_file(path, as_attachment=True)


if __name__ == '__main__':
app.run()

  

Content-Disposition:

  Content-Disposition

  在常规的 HTTP 应答中,Content-Disposition 响应头指示回复的内容该以何种形式展示,是以内联的形式(即网页或者页面的一部分),还是以附件的形式下载并保存到本地。其可以是inline(默认值,所以可以不指定)或者是attachment,attachment表示附件,浏览器看到这个值一般会弹出一个保持文件的确认框,或者像chrome直接下载。

  

Flask send_file函数如何避免绝对路径长尾词遍历?

 ① 网安学习成长路径思维导图
 ② 60+网安经典常用工具包
 ③ 100+SRC漏洞分析报告
 ④ 150+网安攻防实战技术电子书
 ⑤ 最权威CISSP 认证考试指南+题库
 ⑥ 超1800页CTF实战技巧手册
 ⑦ 最新网安大厂面试题合集(含答案)
 ⑧ APP客户端安全检测指南(安卓+IOS)

漏洞分析

  漏洞的触发是在send_file中,我们跟进看一下

  flask.helpers.send_file

  继续跟进查看

  werkzeug.utils.send_file

  我们在本地构造一个简单的语句进行尝试

>>> import os.path
>>> _root_path = "path/to/mySafeStaticDir"
>>> path_or_file = "/../../../../../../../etc/passwd"
>>> os.path.join(_root_path,path_or_file)
'/../../../../../../../etc/passwd'

  我们发现os.path.join使用不受信任的输入调用时不安全的。当os.path.join调用遇到绝对路径时,它会忽略在该点之前遇到的所有参数并开始使用新的绝对路径。当参数可控时,我们控制恶意参数输入绝对路径,os.path.join会完全忽略静态目录。所以,当os.path.join来获取来自flask.send_file的不受信任的输入时,可能会目录遍历攻击。

漏洞复现

  我们在本地构造简单的代码进行测试,获取从外部传入的参数filename

from flask import Flask, request
from flask import send_file

app = Flask(__name__)


@app.route('/download')
def downloadFile():
filename = request.args.get('filename')
return send_file(filename, as_attachment=True)

if __name__ == '__main__':
app.run()

  通过控制filename为绝对路径,就实现了目录穿越漏洞

  

总结反思

  这个漏洞非常的有趣,漏洞的修复是可以使用flask.safe_join加入不受信任的路径或用flask.send_file调用替换flask.send_from_directory调用。

  这个漏洞虽然很简单,但是在 github 上很多用 python 开发的项目都用了这个函数,如果不加以修复,会造成很大的危害。

  更多靶场实验练习、网安学习资料,请点击这里>>

搜索

复制

合天智汇:合天网络靶场、网安实战虚拟环境
标签:绝对路径

本文共计1302个文字,预计阅读时间需要6分钟。

Flask send_file函数如何避免绝对路径长尾词遍历?

平时接触到的Python项目并不多,对Python的代码审查更是没有接触。偶然间朋友发现了一个漏洞——Flask的send_file函数导致的绝对路径遍历,感觉打开了新世界的大门,即便是初学者也跃跃欲试。

平时接触到的 python 项目并不多,对 python 的代码审计更是没有接触,偶然朋友发来了一个漏洞 Flask send_file函数导致的绝对路径遍历 ,感觉打开了新世界的大门,于是就以一个初学者的角度,进行复现分析一下。

  平时接触到的 python 项目并不多,对 python 的代码审计更是没有接触,偶然朋友发来了一个漏洞Flask send_file函数导致的绝对路径遍历,感觉打开了新世界的大门,于是就以一个初学者的角度,进行复现分析一下。详情也可以根据Python : Flask Path Traversal Vulnerability进行分析学习

send_file 的妙用

  在以 flask 框架开发的系统中,为了直接实现用户访问某一个 URL 时就可以下载到文件,我们就使用send_file来实现

from flask import Flask
from flask import send_file

app = Flask(__name__)


@app.route('/download')
def downloadFile():
path = "test.txt"
return send_file(path)


if __name__ == '__main__':
app.run()

  我们看到 如此运行的效果是直接返回了文件的内容,浏览器并没有识别成一个文件下载下来。

  要想让浏览器识别成为文件下载的话,只需要加上as_attachment=True

from flask import Flask
from flask import send_file

app = Flask(__name__)


@app.route('/download')
def downloadFile():
path = "test.txt"
return send_file(path, as_attachment=True)


if __name__ == '__main__':
app.run()

  

  

  当下载的文件名是中文时

from flask import Flask
from flask import send_file

app = Flask(__name__)


@app.route('/download')
def downloadFile():
path = "测试.txt"
return send_file(path, as_attachment=True)


if __name__ == '__main__':
app.run()

  

Content-Disposition:

  Content-Disposition

  在常规的 HTTP 应答中,Content-Disposition 响应头指示回复的内容该以何种形式展示,是以内联的形式(即网页或者页面的一部分),还是以附件的形式下载并保存到本地。其可以是inline(默认值,所以可以不指定)或者是attachment,attachment表示附件,浏览器看到这个值一般会弹出一个保持文件的确认框,或者像chrome直接下载。

  

Flask send_file函数如何避免绝对路径长尾词遍历?

 ① 网安学习成长路径思维导图
 ② 60+网安经典常用工具包
 ③ 100+SRC漏洞分析报告
 ④ 150+网安攻防实战技术电子书
 ⑤ 最权威CISSP 认证考试指南+题库
 ⑥ 超1800页CTF实战技巧手册
 ⑦ 最新网安大厂面试题合集(含答案)
 ⑧ APP客户端安全检测指南(安卓+IOS)

漏洞分析

  漏洞的触发是在send_file中,我们跟进看一下

  flask.helpers.send_file

  继续跟进查看

  werkzeug.utils.send_file

  我们在本地构造一个简单的语句进行尝试

>>> import os.path
>>> _root_path = "path/to/mySafeStaticDir"
>>> path_or_file = "/../../../../../../../etc/passwd"
>>> os.path.join(_root_path,path_or_file)
'/../../../../../../../etc/passwd'

  我们发现os.path.join使用不受信任的输入调用时不安全的。当os.path.join调用遇到绝对路径时,它会忽略在该点之前遇到的所有参数并开始使用新的绝对路径。当参数可控时,我们控制恶意参数输入绝对路径,os.path.join会完全忽略静态目录。所以,当os.path.join来获取来自flask.send_file的不受信任的输入时,可能会目录遍历攻击。

漏洞复现

  我们在本地构造简单的代码进行测试,获取从外部传入的参数filename

from flask import Flask, request
from flask import send_file

app = Flask(__name__)


@app.route('/download')
def downloadFile():
filename = request.args.get('filename')
return send_file(filename, as_attachment=True)

if __name__ == '__main__':
app.run()

  通过控制filename为绝对路径,就实现了目录穿越漏洞

  

总结反思

  这个漏洞非常的有趣,漏洞的修复是可以使用flask.safe_join加入不受信任的路径或用flask.send_file调用替换flask.send_from_directory调用。

  这个漏洞虽然很简单,但是在 github 上很多用 python 开发的项目都用了这个函数,如果不加以修复,会造成很大的危害。

  更多靶场实验练习、网安学习资料,请点击这里>>

搜索

复制

合天智汇:合天网络靶场、网安实战虚拟环境
标签:绝对路径