Flask-上传至S3 / Google Cloud时需要使用secure_filename()吗?

问题描述 投票:0回答:1

file uploads的Flask文档中,他们建议在存储文件之前使用secure_filename()清除文件名。

这是他们的示例:

uploaded_file = request.files['file']
if uploaded_file:
    filename = secure_filename(uploaded_file.filename) # <<<< note the use of secure_filename() here
    file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
    return redirect(url_for('display_file',
                            filename=filename))

文档说:

现在的问题是,有一个称为“永不信任用户输入”。对于上载文件的文件名也是如此。所有提交的表单数据可能是伪造的,文件名可能很危险。对于请记住:始终使用该功能来保护文件名,然后将其直接存储在文件系统上。

使用异地存储(S3或Google Cloud),我将不会使用Flask将文件存储在Web服务器上。相反,我将重命名上传文件(使用自己的UUID),然后将其上传到其他位置。

示例:

blob = bucket.blob('prompts/{filename}'.format(filename=uuid.uui4()))
blob.upload_from_string(uploaded_file.read(), content_type=uploaded_file.content_type)

在这种情况下,您对吗?[[not需要首先调用secure_filename()吗?

[似乎,因为我(a)将文件的内容读入字符串,然后(b)使用我自己的文件名,所以我的用例不容易受到目录遍历或恶意命令类型的攻击(例如[C0 ]),但我不确定100%。
flask werkzeug
1个回答
0
投票
您是正确的。

[仅当使用"../../../../home/username/.bashrc"的值来构建目的地为文件系统的文件路径时,才需要使用secure_filename函数-例如,作为request.files['file'].filename的参数。

当您使用UUID作为文件名时,无论如何都将忽略用户输入值。

即使没有S3,如果在本地文件系统上使用UUID作为文件路径的文件名段,也可以不使用os.path.join。例如:

secure_filename

在任何一种情况下,您都将UUID存储在数据库中的某个位置。是否选择将原始提供的uploaded_file = request.files['file']
if uploaded_file:
    file_uuid = uuid.uuid4()
    file.save(os.path.join(app.config['UPLOAD_FOLDER'], file_uuid))
    # Rest of code
值存储在旁边?

如果您希望用户在

他们上传文件时看到文件的原始名称,这可能很有意义。在那种情况下,无论如何都要通过request.files['file'].filename来运行值,因此永远不会出现这样的情况:前端向用户显示包含secure_filename

文件的列表
../../../../ohdear.txt还指出了其他一些功能:

将文件名传递给它,它将返回它的安全版本。这个然后可以将文件名安全地存储在常规文件系统中并传递到:func:the secure_filename docstring。返回的文件名是仅ASCII的字符串以获得最大的便携性。在Windows系统上,该功能还可以确保该文件不是以特殊设备文件之一命名。

secure_filename

© www.soinside.com 2019 - 2024. All rights reserved.