File upload features are super handy in web apps; they let users share all kinds of files like documents, photos, videos, and more. But if they aren’t implemented properly, file uploads can open up a massive security hole for attackers to exploit.
What are file upload vulnerabilities?
File upload vulnerabilities occur when a web application fails to implement proper security controls and validation mechanisms during the file upload process. These vulnerabilities can be exploited by attackers to gain unauthorized access, execute malicious code, or disrupt the application’s normal operations.
How do they occur?
- Lack of file type validation:
- Web applications often use the
Content-Type
header or the file extension to determine the type of file being uploaded. - If the application relies solely on these methods without additional validation, an attacker can manipulate the
Content-Type
header or change the file extension to bypass file type restrictions. - Example: An attacker can set the
Content-Type
header toimage/jpeg
while uploading a PHP script file (e.g.,malicious.php.jpg
), allowing the execution of malicious code on the server if not properly validated.
- Web applications often use the
- Lack of file content validation:
- Even if the file type is allowed, the application may not inspect the actual contents of the uploaded file for malicious code or patterns.
- Examples:
- An attacker can embed malicious code or scripts within the metadata or comments of an image file, which can be executed on the server if not properly validated.
- An attacker can craft a PDF file with embedded JavaScript code, which can be executed in certain environments if not properly sanitized.
- Insecure file naming and storage:
- If the application does not sanitize or rename the uploaded file names, an attacker can craft file names with directory traversal sequences (e.g., “../”) to access or overwrite sensitive files on the server.
- Example: An attacker uploads a file named
../../etc/passwd
and exploits a path traversal vulnerability to access the system’s password file if the application does not properly sanitize the file path.
- Lack of file size restrictions:
- If the application does not impose limits on the size of uploaded files, an attacker can upload excessively large files to consume server resources, leading to a denial-of-service condition.
- Example: An attacker uploads a multi-gigabyte file, causing the server to run out of disk space or exhaust memory, resulting in application downtime or crashes.
- Insecure file handling and execution:
- If the application processes or executes uploaded files in an insecure manner, an attacker can leverage this to execute malicious code or gain unauthorized access.
- Example: An attacker uploads a malicious script file (e.g., a PHP or JSP file), and the application executes it on the server without proper security checks, leading to remote code execution.
Unrestricted file uploads can lead to deploying a web shell
A web shell is a script (often written in languages like PHP, ASP, or JSP) that runs on the web server and provides an attacker with remote access and control over the server. Once a web shell is deployed, the attacker can execute arbitrary commands, browse the file system, upload/download files, and potentially gain full control of the server.
When a web application allows unrestricted file uploads without proper validation and security measures, an attacker can exploit this vulnerability to upload a malicious file containing a web shell script. If the application doesn’t validate the file type, content, or execution permissions, the attacker’s uploaded web shell script can be executed on the server.
Here’s a typical scenario:
- The attacker discovers file upload functionality in the web application that lacks proper security controls.
- The attacker creates a file containing a web shell script (e.g.,
webshell.php
with malicious PHP code). - The attacker uploads the malicious file (
webshell.php
) to the server, bypassing any file type or content restrictions due to the unrestricted file upload vulnerability. - If the web application executes the uploaded file or stores it in a location that allows execution (e.g., the web server’s document root), the attacker’s web shell script is now running on the server.
- The attacker can then access the web shell (e.g.
http://example.com/webshell.php
) and gain remote control over the server, executing arbitrary commands and potentially compromising the entire system.
Obfuscating file extensions
Even the most thorough blacklists for blocking file types can potentially be sidestepped by clever attackers using some sneaky obfuscation tricks. Here are some examples of how they might pull it off:
- First up, case sensitivity mismatches. Let’s say the validation code is set to block
.php
files, but it’s case-sensitive. So an attacker uploadsexploit.pHp
– that’ll slip right through since the code doesn’t recognize the uppercase “P” as a PHP file. But if the code that maps file extensions to MIME types down the line isn’t case-sensitive, bam—that malicious PHP file gets executed on the server.
- Another trick is using multiple file extensions. Depending on how the filename parsing works, something like
exploit.php.jpg
might be interpreted as either a PHP script or a JPG image file. If it gets read as PHP, the attacker is in.
- Or attackers can try adding trailing characters that some systems might just ignore or strip out, like
exploit.php.
with that trailing dot and space. If those get removed before execution, the.php
part is left behind.
- URL-encoding shenanigans can work too. Like if
exploit%2Ephp
gets validated without being fully decoded but then decoded properly by the server later, bypassing the filters.
- Null byte injection by adding like
%00
or semicolons before extensions (exploit.asp%00.jpg
) can also mess with interpretations between different code layers.
- Finally, multibyte Unicode obfuscation using crazy character sequences that might convert to dots or null bytes after conversions, like
xC0 x2E
becoming just.
in some environments,.
- The key thing is that all these tricks try to create discrepancies between the validation logic and how the files actually get processed at different points in the system. If any of those obfuscations aren’t caught, bam, malicious file execution.
So blacklists alone aren’t enough; they have to be validated comprehensively using stuff like actual file content checks, strict input sanitization, secure naming conventions, and expect attackers to get really creative in how they try to sneak bad files through. Make ’em work for it!
Exploiting file upload race conditions
Okay, let me break this down in a more conversational, human-written way:
Modern web frameworks have definitely leveled up their defenses against nasty file upload attacks. They’re not just blindly accepting uploaded files anymore. Instead, they take some smart precautions first.
The typical flow goes like this: uploaded files get stashed in a temporary, sandboxed directory separate from the main webapp. The filename also gets randomized to avoid overwriting any existing files. Then and only then, do the frameworks run validation checks on this temp file. If it passes muster, only then does it get transferred to its proper storage destination.
Pretty slick process to reduce risk, right? But here’s where developers can still accidentally open up security holes: when they try to reinvent the wheel and build their own custom file upload handling instead of using the framework’s tools.
Not only is doing this securely really tricky to get right, but it can also introduce nasty race condition vulnerabilities that let attackers bypass all those robust validation checks.
A classic example is websites that upload files directly to the main filesystem first, then remove them if validation fails. This is common with sites using antivirus scanning to check for malware on uploads. That whole validate-then-remove process might seem fast, taking just milliseconds. But in that tiny window where the uploaded file exists on the server, bam, attackers could potentially find a way to execute it.
These race-condition flaws are crazy subtle. It is nearly impossible to detect through normal black-box testing and poking around unless you can somehow leak the site’s source code to analyze.
So while modern frameworks have raised the bar with secure upload handling, developers still need to be super careful about introducing custom vulnerabilities through sloppy implementation or weird timing issues. I can’t get complacent! Staying secure requires constant vigilance.
Conclusion
At the end of the day, file upload vulnerabilities remain a significant security risk that cannot be ignored by web application developers and security teams. While implementing robust validation controls and security measures can mitigate these risks, the ever-evolving nature of cyber threats means that vigilance and continuous improvement are crucial.
References
https://portswigger.net/web-security/file-upload#Overriding-the-server-configuration
https://portswigger.net/web-security/file-upload#exploiting-flawed-validation-of-file-uploads
https://www.bugbountyhunter.com/hackevents/report?id=690
https://portswigger.net/web-security/file-upload#exploiting-file-upload-race-conditions
https://www.exploit-db.com/docs/english/45074-file-upload-restrictions-bypass.pdf
About me
Hello, I’m Harshi Gupta, a seasoned penetration tester with expertise in both internal and external assessments. Cybersecurity is not just a career path for me; it’s my hobby and passion. With a wealth of experience in identifying and mitigating security vulnerabilities, I am dedicated to ensuring the resilience of organizations’ digital assets. For networking opportunities and engaging discussions, feel free to reach out to me via LinkedIn and Twitter.