Link Search Menu Expand Document

Unrestricted File Upload

Play SecureFlag Play Labs on this vulnerability with SecureFlag!

  1. Unrestricted File Upload
    1. Description
    2. Impact
    3. Scenarios
    4. Prevention
    5. Testing

image

Description

Unrestricted File Upload vulnerabilities occur when a web application fails to properly validate file types before accepting uploads. Without these checks, an attacker can craft a malicious file to bypass application-layer defenses and potentially gain complete control of the system.

The OWASP Top 10 refers to Unrestricted File Uploads as a significant risk, and for good reason. They provide an easy entry point for attackers and can be used to escalate access within the system.

Impact

Unrestricted File Upload vulnerabilities are often severe because they can allow attackers to execute code on the server. For instance, in April 2025, a critical vulnerability in SAP NetWeaver Visual Composer was discovered. This flaw allowed unauthenticated attackers to upload malicious files and run arbitrary commands on the server, compromising system integrity and confidentiality.

Attackers can exploit these vulnerabilities in different ways, depending on the programming language and the specific weakness in the code. Even when security checks exist, they are often missing or implemented incorrectly, leaving the application exposed. Common controls that can be bypassed include:

  • MIME-type validation
  • Checking the file extension against a deny list
  • Image header checks

These flaws can lead to Command Injection, XSS, Denial of Service attacks, phishing pages, and other risks depending on the application and file type.

Scenarios

To better understand the risk, here’s an example of an Unrestricted File Upload vulnerability in PHP. In this case, a missing validation check in the script can be exploited to upload and execute malicious files.

The code below lets a user upload a picture of a flag (in this case, a SecureFlag picture) to the web server. The HTML form uses a file input field to let the user select a file for upload.

<form action="upload_flagpics.php" method="post" enctype="multipart/form-data">

  Choose a file to upload:
  <input type="file" name="filename"/>
  <br/>
  <input type="submit" name="submit" value="Submit"/>

</form>

Upon submission, the form then sends the file to upload_flagpics.php on the web server. The file is stored in a temporary location by PHP until it is either retrieved or discarded on the server side. The file is then sent to a more permanent directory called flagpics/.

// Define the target location where the uploaded SecureFlag picture
// is going to be saved.

$target = "flagpics/" . basename($_FILES['uploadedfile']['name']);

// Move the uploaded file to the new location.
if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target))
{
	echo "The picture has been successfully uploaded.";
}
else
{
	echo "There was an error uploading the picture, please try again.";
}

Unfortunately, the above code does not validate the file type being uploaded, and if the flagpics/ directory is accessible in the web document root, a malicious actor would be able to upload a file with the name malicious.php. This filename, ending in .php, can then be executed by the web server. A malicious actor could additionally send:

<?php
system($_GET['cmd']);
?>

If this file is successfully installed by the attacker, they will be able to run arbitrary commands using a URL to execute, such as:

http://www.vulnerableapp.com/upload_dir/malicious.php?cmd=ls%20-l

As a result, the attack can run the ls -al command.

Prevention

When reviewing upload functionality, developers should check:

  • File extensions and MIME types are properly filtered.
  • Uploaded files cannot contain executable JavaScript or HTML.
  • File headers are not exposed when downloaded.
  • Uploaded files cannot escape their intended storage location.

Best practices for secure file uploads include:

  • Use an allow list to accept only safe, non-executable file types.
  • Make sure file names don’t include directory traversal characters like ../.
  • Set folder permissions so uploaded files cannot be executed.
  • Store uploads in directories that are not publicly accessible.
  • When files are downloaded, useX-Content-Type-options: nosniff and Content-Disposition headers to force safe handling
  • Scan uploaded files for viruses immediately.
  • Enforce size limits and block archive formats like ZIP.

Testing

Check that user-uploaded files are stored in designated directories outside the web root. If the application needs to display or allow downloads, serve the files securely using octet-stream downloads or from a separate domain.


Table of contents