This weakness occurs when a web application accepts file uploads without properly validating the file type, allowing an attacker to upload executable scripts…
This weakness occurs when a web application accepts file uploads without properly validating the file type, allowing an attacker to upload executable scripts, archives, or other dangerous files. If the server processes or executes these files, an attacker can gain remote code execution, deface content, or compromise the entire system. Proper file type validation is essential to prevent this risk.
02How It Happens
Applications often allow users to upload files—profile pictures, documents, media—without adequately checking what is actually being uploaded. An attacker can rename a PHP script to have a .jpg extension, or upload a .zip archive containing executable files, or use MIME type spoofing to bypass weak client-side checks. If the server stores these files in a web-accessible directory and executes them (or auto-extracts archives), the attacker's code runs with the server's privileges. The vulnerability is compounded when validation relies only on file extension, MIME type headers (which are user-controlled), or client-side checks that can be bypassed.
03Real-World Impact
Successful exploitation typically leads to remote code execution, allowing an attacker to read sensitive files, modify or delete data, install malware, or pivot to other systems on the network. In content management systems, attackers can upload malicious plugins or themes. In document management systems, they can upload archives that extract to overwrite legitimate files. The impact ranges from site defacement to complete server compromise, depending on file permissions and server configuration.
Why it's vulnerable: The code accepts any filename and saves it directly to a web-accessible directory without checking the file type, extension, or content. An attacker can upload shell.php or malware.exe and execute it.
Fixed pattern
from flask import Flask, request
import os
import magic
app = Flask(__name__)
UPLOAD_DIR = '/var/www/uploads'
ALLOWED_TYPES = {'image/jpeg', 'image/png', 'application/pdf'}
ALLOWED_EXTENSIONS = {'.jpg', '.jpeg', '.png', '.pdf'}
@app.route('/upload', methods=['POST'])
def upload_file():
file = request.files['file']
filename = file.filename
# Validate extension
_, ext = os.path.splitext(filename)
if ext.lower() not in ALLOWED_EXTENSIONS:
return 'Invalid file type', 400
# Validate MIME type by reading file content
mime = magic.from_buffer(file.read(1024), mime=True)
if mime not in ALLOWED_TYPES:
return 'Invalid file type', 400
file.seek(0)
file.save(os.path.join(UPLOAD_DIR, filename))
return 'File uploaded successfully'
Why it's vulnerable: Extension-only validation is trivial to bypass—an attacker can rename shell.php to shell.php.jpg or use null-byte injection. The MIME type from $_FILES['type'] is also user-controlled and unreliable.
Maintain an allowlist of safe file types (by MIME type and extension) rather than a blocklist; reject everything else by default.
Validate file content, not just headers. Use file magic number inspection (e.g., finfo_file() in PHP, python-magic in Python) to verify the actual file type, not just the extension or Content-Type header.
Store uploads outside the web root or in a directory configured to not execute scripts (e.g., via .htaccess or web server configuration).
Rename uploaded files to remove user-controlled names and prevent directory traversal or extension-based attacks.
Set appropriate file permissions so uploaded files are not executable and cannot be modified by other users.
Scan uploaded files with antivirus or malware detection if handling user-supplied documents in sensitive environments.
06Signs You May Already Be Affected
Check your upload directories for unexpected file types (e.g., .php, .exe, .sh files in a directory meant for images). Review web server logs for requests to unusual file paths or suspicious file access patterns. Look for unexpected admin accounts or new files in system directories that you did not create. If you find evidence of unauthorized file uploads, isolate the affected system and review access logs to determine the scope of compromise.