7

我有一个表单,当表单发布时,它会向我的 Flask 应用程序发送一个字符串。该字符串是一个文件路径,所以我想确保它不包含任何讨厌的东西,比如../../../etc/passwd. Flask 使用的 Werkzeug 有一个方便的函数,称为secure_filename从文件名中去除讨厌的东西。不幸的是,当输入像 的完整路径时templates/example.html,它会将 转换/_,所以我们最终得到templates_example.html

那么,将路径分成多个级别似乎是明智的,所以我分别发送templatesexample.html然后在服务器上再次将它们连接在一起。这很好用,除了路径可以任意深。我可以串起来dir1/dir2/dir3/dir4并希望没有人比 更深dir4,但这似乎很愚蠢。

处理未知深度路径验证的正确方法是什么?验证不同?以不同的方式发送数据?对路径进行不同的编码,然后在服务器上对其进行解码?

4

2 回答 2

10

对于这种情况safe_join,如果用户试图离开路径,Flask 会引发 404:

>>> safe_join('/foo/bar', 'test')
'/foo/bar/test'
>>> safe_join('/foo/bar', 'test/../other_test')
'/foo/bar/other_test'
>>> safe_join('/foo/bar', 'test/../../../etc/htpassw')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mitsuhiko/Development/flask/flask/helpers.py", line 432, in safe_join
    raise NotFound()
werkzeug.exceptions.NotFound: 404: Not Found
于 2011-08-17T10:47:24.953 回答
2

您可以使用werkzeug.routing.PathConverter来处理任意路径,如下所示:

from flask import Flask
app = Flask(__name__)

@app.route("/arbitrary/<path:my_path>")
def arbitrary_path(my_path):
    return my_path

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

通过上面过于简化的示例,您可以看到如果您访问http://127.0.0.1:5000/arbitrary/dir1/dir2/dir3/dir4它将返回dir1/dir2/dir3/dir4,如果您访问http://127.0.0.1:5000/arbitrary/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dir10它将返回dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dir10

于 2011-08-16T18:33:40.583 回答