You are correct.

You only need to use the secure_filename function if you are using the value of request.files['file'].filename to build a filepath destined for your filesystem - for example as an argument to os.path.join.

As you're using a UUID for the filename, the user input value is disregarded anyway.

Even without S3, it would also be safe NOT to use secure_filename if you used a UUID as the filename segment of the filepath on your local filesystem. For example:

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

In either scenario you'd then store the UUID somewhere in the database. Whether you store the originally provided request.files['file'].filename value alongside that is your choice.

This might make sense if you want the user to see the original name of the file when they uploaded it. In that case it's definitey wise to run the value through secure_filename anyway, so there's never a situation where the frontend displays a listing to a user which includes a file called ../../../../ohdear.txt


the secure_filename docstring also points out some other functionality:

Pass it a filename and it will return a secure version of it. This filename can then safely be stored on a regular file system and passed to :func:os.path.join. The filename returned is an ASCII only string for maximum portability. On windows systems the function also makes sure that the file is not named after one of the special device files.

>>> secure_filename("My cool movie.mov")
'My_cool_movie.mov'
>>> secure_filename("../../../etc/passwd")
'etc_passwd'
>>> secure_filename(u'i contain cool \xfcml\xe4uts.txt')
'i_contain_cool_umlauts.txt'
Answer from v25 on Stack Overflow
Top answer
1 of 1
7

You are correct.

You only need to use the secure_filename function if you are using the value of request.files['file'].filename to build a filepath destined for your filesystem - for example as an argument to os.path.join.

As you're using a UUID for the filename, the user input value is disregarded anyway.

Even without S3, it would also be safe NOT to use secure_filename if you used a UUID as the filename segment of the filepath on your local filesystem. For example:

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

In either scenario you'd then store the UUID somewhere in the database. Whether you store the originally provided request.files['file'].filename value alongside that is your choice.

This might make sense if you want the user to see the original name of the file when they uploaded it. In that case it's definitey wise to run the value through secure_filename anyway, so there's never a situation where the frontend displays a listing to a user which includes a file called ../../../../ohdear.txt


the secure_filename docstring also points out some other functionality:

Pass it a filename and it will return a secure version of it. This filename can then safely be stored on a regular file system and passed to :func:os.path.join. The filename returned is an ASCII only string for maximum portability. On windows systems the function also makes sure that the file is not named after one of the special device files.

>>> secure_filename("My cool movie.mov")
'My_cool_movie.mov'
>>> secure_filename("../../../etc/passwd")
'etc_passwd'
>>> secure_filename(u'i contain cool \xfcml\xe4uts.txt')
'i_contain_cool_umlauts.txt'
🌐
Medium
medium.com › @sujathamudadla1213 › what-is-the-use-of-secure-filename-in-flask-9eef4c71503b
What is the use of secure_filename in flask? | by Sujatha Mudadla | Medium
November 25, 2023 - secure_filename is a function provided by Flask's werkzeug.utils module that is used to sanitize and secure filenames before storing them on the server. This is important for security reasons.
Discussions

python - Secure user-provided filename - Stack Overflow
Part of my app requires the client to request files. Now, a well-behaved client will only request files that are safe to give, but I don't want a user to go about supplying "../../../creditCardInfo... More on stackoverflow.com
🌐 stackoverflow.com
June 2, 2017
Uploading and Displaying a Photo in Flask
Edit: switched to code block format More on reddit.com
🌐 r/learnpython
6
2
December 17, 2020
Import Error when importing secure_filename from Werkzeug.utils : Forums : PythonAnywhere
Thank you!! 2020-06-09 19:19:39,700: Error running WSGI application 2020-06-09 19:19:39,731: ImportError: cannot import name 'secure_filename' 2020-06-09 19:19:39,731: File "/var/www/virtualta_pythonanywhere_com_wsgi.py", line 16, in 2020-06-09 19:19:39,731: from flask_app import app ... More on pythonanywhere.com
🌐 pythonanywhere.com
'Secure' Filenames
An example: if the user supplied a file name of ../../../../../boot/vmlinuz and your app was running as root -bad practice but still common - you might write over your Linux kernel with the uploaded file if your didn't sanitize the input. More on reddit.com
🌐 r/Python
4
6
January 14, 2017
🌐
Beautiful Soup
tedboy.github.io › flask › generated › werkzeug.secure_filename.html
werkzeug.secure_filename — Flask API
Pass it a filename and it will return a secure version of it. This filename can then safely be stored on a regular file system and passed to os.path.join(). The filename returned is an ASCII only string for maximum portability · On windows systems the function also makes sure that the file ...
🌐
Medium
medium.com › @functionbasket › securing-file-upload-in-a-flask-application-and-preventing-path-traversal-attack-031fdd9e2e97
Securing file upload in a Flask Application and preventing path traversal attack | by Swadhin | Medium
January 23, 2025 - Assuming the path is correct, the ... problem secure_filenamefunction can be used to sanitize and secure filenames before storing them on the server....
🌐
PyPI
pypi.org › project › filenames-secure
filenames-secure · PyPI
Simply $ filenames_secure to obscure and restore. Filenames will be CRC-32'd, with restore record kept in an JSON file in the same folder.
      » pip install filenames-secure
    
Published   Jan 04, 2021
Version   0.0.8
🌐
HackerOne
pullrequest.com › blog › secure-file-uploads-in-flask-filtering-and-validation-techniques
Secure File Uploads in Flask: Filtering and Validation Techniques | HackerOne
March 18, 2024 - Understanding these risks is the first step toward securing your Flask application against file upload vulnerabilities. Flask, a micro web framework written in Python, makes it straightforward to handle file uploads. However, the simplicity of implementation does not inherently guarantee security. Let's start with a basic example of handling file uploads in Flask: from flask import Flask, request, redirect, url_for from werkzeug.utils import secure_filename app = Flask(__name__) @app.route('/upload', methods=['POST']) def upload_file(): if 'file' not in request.files: return redirect(request.u
Find elsewhere
🌐
Reddit
reddit.com › r/learnpython › uploading and displaying a photo in flask
r/learnpython on Reddit: Uploading and Displaying a Photo in Flask
December 17, 2020 -

So I'm just getting my feet wet with flask, trying to figure out how to upload and display a photo using the flask documentation. I'm running the following code with debug on, and getting a FileNotFoundError: [Errno 2] No such file or directory: '/path/to/the/uploads/XXXXX.jpeg' (I have swapped the file name for XXXXX, but it's actually a long string of numbers and letters).

The code I'm running is:

import os
from flask import Flask, flash, request, redirect, url_for, render_template, send_from_directory
from werkzeug.utils import secure_filename

UPLOAD_FOLDER = '/path/to/the/uploads'
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

def allowed_file(filename):
    return '.' in filename and \
            filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        if 'file' not in request.files:
            flash('No file part')
            return redirect(request.url)
        file = request.files['file']
        if file.filename == '':
            flash('No selected file')
            return redirect(request.url)
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return redirect(url_for('uploaded_file',
                                    filename=filename))
    return '''
    <!doctype html>
    <title>Upload new File</title>
    <h1>Upload new File</h1>
    <form method=post enctype=multipart/form-data>
        <input type=file name=file>
        <input type=submit value=Upload>
    </form>
    '''

@app.route('/uploads/<filename>')
def uploaded_file(filename):
    return send_from_directory(app.config['UPLOAD_FOLDER'],
                                filename)


@app.route("/hello", methods=['POST', 'GET'])
def index():
    greeting = "Hello World"

    if request.method == "POST":
        name = request.form['name']
        greet = request.form['greet']
        greeting = f"{greet}, {name}"
        return render_template("index.html", greeting=greeting)
    else:
        return render_template("hello_form.html")


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

This is exactly the code from the flask documentation, plus a little bit in the index func from a previous exercise I did with a POST form that collected text input from the user and then displayed it. It seems to me that '/path/to/the/uploads' isn't getting created, so when I upload the jpeg it doesn't go anywhere. It seems to me that app.config should create that path/those directories, but I'm clearly missing something obvious.

🌐
Transloadit
transloadit.com › devtips › efficient-flask-file-uploads-a-step-by-step-guide
Efficient Flask file uploads: a step-by-step guide | Transloadit
secure_filename() prevents directory traversal attacks. Enforcing a file size limit protects against resource exhaustion. ... @app.route('/api/upload', methods=['POST']) def api_upload(): if 'file' not in request.files: return jsonify({'error': ...
🌐
PythonAnywhere
pythonanywhere.com › forums › topic › 27730
Import Error when importing secure_filename from Werkzeug.utils : Forums : PythonAnywhere
from werkzeug.utils import secure_filename from flask import Flask, redirect, render_template, request, url_for from flask_bootstrap import Bootstrap from .helper import upload_file_to_s3 app = Flask(__name__) Bootstrap(app) app.config["DEBUG"] = True app.config.from_object("mysite.config") comments = [] ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'} @app.route("/", methods=["GET", "POST"]) def main(): if request.method == "GET": return render_template("main_page.html", comments=comments) comments.append(request.form["contents"]) return redirect(url_for('main')) #https://www.
🌐
PyPI
pypi.org › project › secure-json
secure-json · PyPI
November 14, 2022 - Secure storage of settings for your python programs. Use strong password ... The library allows you to encrypt your settings stored in json format. It is possible to convert from a simple storage option to an encrypted one. To work with the encrypted version of the settings, you need to pass the startup parameter - the password with which the encryption took place.
      » pip install secure-json
    
Published   Nov 14, 2022
Version   1.1.0
🌐
Reddit
reddit.com › r/python › 'secure' filenames
r/Python on Reddit: 'Secure' Filenames
January 14, 2017 -

Flask's WSGI library werkzeug has a utility function called secure_filename - you're intended to pass the filename of a user uploaded file to it but I'm having trouble understanding what exactly the concern is, and what securing a filename could possibly entail.

The Pooco site notes

what does that secure_filename() function actually do? Now the problem is that there is that principle called “never trust user input”. This is also true for the filename of an uploaded file. All submitted form data can be forged, and filenames can be dangerous. For the moment just remember: always use that function to secure a filename before storing it directly on the filesystem.

What's returned is the exact same filename except I guess sanitized in some way. What my concern is is that I don't really understand what this function accomplishes. I plan on changing the filename of any user submitted file anyways (random uuid string with a suffix of '-small', '-large', etc.). Does it do me any good to first run the filename through secure_filename() and then change the actual filename? Can I just initially change the filename?

🌐
Flask
flask.palletsprojects.com › en › stable › patterns › fileuploads
Uploading Files — Flask Documentation (3.1.x)
For the moment just remember: always use that function to secure a filename before storing it directly on the filesystem.
🌐
Real Python
realpython.com › python-json
Working With JSON Data in Python – Real Python
August 20, 2025 - When you deserialize a JSON file as a Python object, then you can interact with it natively—for example, by accessing the value of the "name" key with square bracket notation ([]). Still, there’s a word of caution here. Import the original dog_data dictionary from before and compare it to frie_data:
🌐
Medium
medium.com › @fridahkimathi › securing-credentials-in-python-59d2092d7b64
Securing Credentials in Python. Introduction | by Fridah Kimathi | Medium
December 12, 2023 - However, if you need to store credentials for personal use and understand the risks involved, you can create a separate Python file (e.g., securing_credentials.py) to store your credentials.
🌐
Filestack
blog.filestack.com › home › why we love flask file uploads (and you should, too!)
Why We Love Flask File Uploads (And You Should, Too!)
July 8, 2025 - You can hard code or retrieve the destination file name using the filename field of the file] request.files object. To acquire a safe version of it, however, use the secure filename() function.
🌐
GitHub
github.com › nthmost › python-secureconfig › blob › master › secureconfig › securejson.py
python-secureconfig/secureconfig/securejson.py at master · nthmost/python-secureconfig
from json import dumps, loads · · from .baseclass import SecureConfig · · __doc__ = '''SecureJson class for simplifying load of encrypted config files. · Subclassed from SecureConfig. · Features: * Instantiate with either a file path or a string of text.
Author   nthmost
🌐
Stack Overflow
stackoverflow.com › questions › 70416975 › python-flask-deployed-on-heroku-importerror-cannot-import-name-secure-filen
Python Flask (deployed on Heroku): ImportError: cannot import name 'secure_filename' from 'werkzeug' when deploying on Heroku - Stack Overflow
Bring the best of human thought and AI automation together at your work. Explore Stack Internal ... Save this question. Show activity on this post. When deploying a flask application on heroku im getting the error above. The problem on heroku is that it installs dependencies and Iam not able to overwrite them then, or? On my local server i just went to flask_uploads.py and change the imports to: from werkzeug.utils import secure_filename from werkzeug.datastructures import FileStorage
🌐
Medium
medium.com › @pavan581 › save-passwords-to-json-file-with-encryption-using-python-9fb9430f22c3
Save passwords to JSON file with encryption using python
October 23, 2020 - JSON file stores as key-value pair similar to dictionary in python, so that we can access the passwords easily using account name or ID. We need to import json package which comes inbuilt when python installed else we can install using command ...