Skip to content

Secure Filenames

Never trust a user-provided filename.

Attackers can try things like:

  • ../../etc/passwd../../etc/passwd
  • special characters that break file systems

Flask/Werkzeug provides secure_filename()secure_filename().

Example

import os
from werkzeug.utils import secure_filename
from flask import Flask, request
 
app = Flask(__name__)
 
UPLOAD_FOLDER = "uploads"
 
 
@app.route("/upload", methods=["POST"])
def upload():
    file = request.files.get("photo")
    if not file:
        return "No file", 400
 
    filename = secure_filename(file.filename)
    os.makedirs(UPLOAD_FOLDER, exist_ok=True)
    save_path = os.path.join(UPLOAD_FOLDER, filename)
    file.save(save_path)
 
    return {"saved_as": filename}, 201
import os
from werkzeug.utils import secure_filename
from flask import Flask, request
 
app = Flask(__name__)
 
UPLOAD_FOLDER = "uploads"
 
 
@app.route("/upload", methods=["POST"])
def upload():
    file = request.files.get("photo")
    if not file:
        return "No file", 400
 
    filename = secure_filename(file.filename)
    os.makedirs(UPLOAD_FOLDER, exist_ok=True)
    save_path = os.path.join(UPLOAD_FOLDER, filename)
    file.save(save_path)
 
    return {"saved_as": filename}, 201

Best practices for production

  • Rename uploaded files (UUID) instead of using original name
  • Store metadata in DB (who uploaded, when, original name)
  • Set an upload size limit (MAX_CONTENT_LENGTHMAX_CONTENT_LENGTH)
  • Validate extensions and MIME type
  • Consider storing files in object storage (S3) rather than the app server

If this helped you, consider buying me a coffee ☕

Buy me a coffee

Was this page helpful?

Let us know how we did