A File Upload Vulnerability occurs when an application allows users to upload files to the server without proper validation and sanitization. This can lead to various security issues, such as malware infections, unauthorized access, and data breaches.
Consider a vulnerable file upload endpoint in a Flask application:
from flask import Flask, request, send_from_directory
import os
app = Flask(__name__)
UPLOAD_FOLDER = '/var/www/uploads'
@app.route('/upload', methods=['POST'])
def upload_file():
if 'file' not in request.files:
return 'No file part', 400
file = request.files['file']
if file.filename == '':
return 'No selected file', 400
if file:
file.save(os.path.join(UPLOAD_FOLDER, file.filename))
return 'File uploaded successfully', 200
if __name__ == '__main__':
app.run(debug=True)
In this example, the server saves the uploaded file directly to the /var/www/uploads
directory without any validation or sanitization, making it vulnerable to malicious file uploads.
Ensure that only allowed file types can be uploaded. This can be done by checking the file extension and MIME type.
from flask import Flask, request, send_from_directory
import os
app = Flask(__name__)
UPLOAD_FOLDER = '/var/www/uploads'
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
def allowed_file(filename):
return '.' in filename and \\
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/upload', methods=['POST'])
def upload_file():
if 'file' not in request.files:
return 'No file part', 400
file = request.files['file']
if file.filename == '':
return 'No selected file', 400
if file and allowed_file(file.filename):
file.save(os.path.join(UPLOAD_FOLDER, file.filename))
return 'File uploaded successfully', 200
return 'File type not allowed', 400
if __name__ == '__main__':
app.run(debug=True)
Sanitize file names to prevent directory traversal attacks and other malicious activities.
import re
def sanitize_filename(filename):
return re.sub(r'[^\\w\\.-]', '', filename)# Remove any non-alphanumeric characters
@app.route('/upload', methods=['POST'])
def upload_file():
if 'file' not in request.files:
return 'No file part', 400
file = request.files['file']
if file.filename == '':
return 'No selected file', 400
if file and allowed_file(file.filename):
sanitized_filename = sanitize_filename(file.filename)
file.save(os.path.join(UPLOAD_FOLDER, sanitized_filename))
return 'File uploaded successfully', 200
return 'File type not allowed', 400
Store uploaded files in a directory outside the web root to prevent direct access via### Prevention Measures (Continued)
Integrate antivirus scanning to check uploaded files for malicious content.