Overview
This vulnerability occurs when an application allows users to upload files without sufficiently restricting the file type, file content, or storage location. Attackers can upload malicious files disguised as benign ones (e.g., a PHP script namedavatar.jpg.php or shell.php saved as image.gif). If the server later executes or serves this file incorrectly, it can lead to Remote Code Execution (RCE), Cross-Site Scripting (XSS), or Denial of Service (DoS). 📁💣
Business Impact
Unrestricted file uploads are extremely dangerous:- Remote Code Execution: Uploading and executing a web shell (e.g.,
.php,.jsp,.aspx) grants the attacker full control over the server. - Cross-Site Scripting (XSS): Uploading HTML or SVG files containing JavaScript can lead to stored XSS attacks against other users who view the file.
- Denial of Service: Uploading extremely large files or files designed to crash parsers (e.g., “zip bombs”) can exhaust server resources.
- Phishing/Malware Distribution: The site can be used to host malicious files targeting users.
Reference Details
CWE ID: CWE-434
OWASP Top 10 (2021): A04:2021 - Insecure Design
Severity: Critical (if RCE is possible)
Framework-Specific Analysis and Remediation
This is a common design flaw where developers don’t fully consider the implications of file uploads. Robust defense requires multiple layers:- Strict Allow-list Validation: Only permit specific, safe file extensions (e.g.,
.jpg,.png,.pdf). Never rely on a block-list. - Content Type Verification: Check the
Content-Typeheader, but do not trust it solely. Validate it against the extension. - File Content Inspection: Use libraries (like
python-magic,Apache Tika) to verify the file’s actual content matches the claimed type (e.g., ensure a.jpgfile actually contains JPEG data). - Rename Files: Store uploaded files with a randomly generated filename and without the original extension. Store the original filename and content type separately in a database if needed.
- Secure Storage Location: Store uploaded files outside the web root or in a directory where server-side script execution is disabled (e.g., via
.htaccessor Nginx config). - Serve Files Securely: Serve files with the correct
Content-Typeand addContent-Disposition: attachmentto force download for potentially risky types. Consider using a separate domain or CDN for user uploads.
- Python
- Java
- .NET(C#)
- PHP
- Node.js
- Ruby
Framework Context
Handlingrequest.FILES in Django or request.files in Flask without proper validation.Vulnerable Scenario 1: Basic Upload without Validation
Vulnerable Scenario 2: Relying Only on Content-Type Header
Mitigation and Best Practices
Validate the extension against an allow-list. Use a library likepython-magic to check the actual file content. Generate a random filename. Store the file outside the web root or in a non-executable location.Secure Code Example
Testing Strategy
Attempt to upload files with disallowed extensions (.php, .html, .exe). Attempt to upload files with double extensions (.jpg.php). Attempt to upload a valid PHP script renamed to .jpg. Attempt to upload a file with a correct extension but incorrect content (e.g., text file named .png). Verify that all attempts except legitimate, allowed files are rejected. Check the storage location and filenames on the server.
