PYTHON
Secure File Upload Validation and Storage in Python Flask
Learn to securely handle file uploads in Python Flask, implementing robust checks for file type, size, and storing files safely outside the web root to prevent attacks.
import os
from flask import Flask, request, redirect, url_for, flash
from werkzeug.utils import secure_filename
UPLOAD_FOLDER = '/path/to/secure/uploads'
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}
MAX_FILE_SIZE = 5 * 1024 * 1024 # 5 MB
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = MAX_FILE_SIZE # Enforce max file size globally
app.secret_key = 'supersecretkey'
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/upload', 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 not allowed_file(file.filename):
flash('Invalid file type')
return redirect(request.url)
# Optional: Check file content type more rigorously if possible, e.g., with python-magic
# For simplicity, we rely on extension here, but it's not foolproof.
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
# Ensure the upload folder exists
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
flash('File successfully uploaded')
return redirect(url_for('upload_file'))
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>
'''
if __name__ == '__main__':
# In a real application, ensure UPLOAD_FOLDER has appropriate permissions
# and is NOT directly accessible via the web server.
app.run(debug=True)
How it works: This Python Flask snippet demonstrates secure file upload practices. It defines `ALLOWED_EXTENSIONS` and `MAX_FILE_SIZE` to validate uploaded files, rejecting invalid types and oversized files early. The `secure_filename` function from `werkzeug.utils` is crucial for sanitizing filenames, preventing directory traversal attacks. Files are saved to a designated `UPLOAD_FOLDER` which should be configured outside the web server's public document root to prevent direct access, adding a significant layer of security. This multi-layered validation helps prevent malicious file uploads.