17. File Upload Vulnerability

File Upload Vulnerability
Category: #File-Based-Attack
Attack: Unrestricted file uploads allow attackers to upload malicious files to a server. These files could include scripts, viruses, or executables that, when accessed, compromise the system.
Attack Code Example (Uploading a PHP Web Shell):
<?php system($_GET['cmd']); ?>
An attacker uploads this PHP file and then accesses it through a URL like http://vulnerable-site.com/uploads/shell.php?cmd=ls
, executing arbitrary system commands on the server.
Vulnerable Code Example (Python Flask with Unrestricted Upload):
@app.route('/upload', methods=['POST'])
def upload_file():
file = request.files['file']
file.save(os.path.join('/uploads', file.filename)) # No file validation, allowing dangerous files
return "File uploaded successfully"
Remediation Steps:
- File Type Validation: Only allow uploads of specific file types (e.g., images or text files). Reject executable files (e.g.,
.exe
,.php
,.js
). - Use Safe Storage Locations: Store uploaded files in a directory separate from the web root to prevent direct access.
- Rename Uploaded Files: Use random or hashed names for uploaded files to prevent predictable file names.
- Limit File Size: Restrict the maximum file size to avoid resource exhaustion attacks.
Safe Code Example (Python Flask with File Type Validation):
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():
file = request.files['file']
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join('/safe_uploads', filename))
return "File uploaded successfully"
else:
return "Invalid file type", 400
Reference: OWASP Unrestricted File Upload