17. File Upload Vulnerability

Post image

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