File Upload Attacks (Part 2)

June 16, 2021

File upload is one of the most common functionalities application has to offer. This functionality, however, is implemented in many different forms based on the application’s use case. While some applications only allow uploading a profile picture and support only image-related extensions, on the other hand, some applications support other extensions based on their business case. Storing and retrieving these files on the server-side is again a huge task and required to be handled with caution.

Due to the involved complexity and level of caution that is required to implement a file upload functionality, this becomes one of the interesting attack vectors and can open doors to multiple critical security vulnerabilities such as Remote Code Execution. In this blog series, we will be focusing on various File Upload Attacks, Bypasses, and some robust mitigation around them from both an attacker’s well a defender’s perspective.

File Upload Attacks

As discussed in the File Upload Attacks: Part — 1 that the file upload functionality enables a great attack surface from a threat actor or attacker’s perspective. In the final part of the File Upload Attacks series, we will be discussing the remaining attacks that one may encounter while testing File Upload functionality. We will also talk about some of the general bypasses and some tips & tricks to execute a successful attack scenario.

The below Mindmap gives a picture of various attacks that are possible when an application implements File Upload Functionality. This series of blogs will be based on this mindmap itself.

Pixel Flood Attack

A very simple attack that can be tested whenever you see a file upload functionality accepting images. In Pixel Flood Attack, an attacker attempts to upload a file with a large pixel size that results in consuming server resources in a way that the application may end up crashing. This can lead to a simple application-level denial of service like scenario. A lot of modern application these days utilize third-party libraries to process heavy images and convert them into small-sized image in order to save storage and processing power. However, some of these libraries used for image processing may be vulnerable to Pixel Flood attack and can result in resource consumption or Application-Level Denial of Service attack.

In order to exploit Pixel Flood Attack, one can try the following steps:

  1. Navigate to https://www.resizepixel.com/ and resize an image with 64250*64250px.
  2. Go to the vulnerable application having the option to upload an image file.
  3. Upload the file generated from “step-1” and observe the server’s response.
  4. If the server takes too long to respond or if the application became inaccessible, confirm with another device, if the lag/accessibility issue happens, the application is vulnerable to pixel flood attack.

Cross-Site Scripting

While performing testing on file upload functionality, there are multiple ways to execute a cross-site scripting attack scenario. Cross-site scripting can be performed via uploading malicious files such as an SVG or HTML file, by changing the file name to cross-site scripting payload and other ways as well.

Cross-Site Scripting via SVG File Upload: An application that doesn’t sanitize and validates the content of an image file and allows to upload an SVG file, it is possible for an attacker to inject the SVG file with a malicious payload that may lead to cross-site scripting attack. This is one of the most common files that I have identified while testing the file upload functionalities.

In order to exploit XSS using SVG File, one can try the following steps:

  1. Create an SVG file containing a cross-site scripting payload. For example:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
   <polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>
   <script type="text/javascript">
      alert(document.domain);
   </script>
</svg>

2. Now, navigate to the file upload functionality and upload this malicious SVG file.

3. Open the SVG file or Go to the endpoint that calls the SVG file and if the application is vulnerable, you will observe a Cross-Site Scripting execution.

Payloads: https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20Injection

Cross-Site Scripting via Image Name: Similar to the Server-Side Injection via file upload attack, as discussed in part-1 of the series, it is possible to perform a Cross-Site Scripting attack by uploading a file having its name as “Cross-Site Scripting Payload”. When the application will render this file name, if there is a lack of input validation/sanitization, the payload will be processed and cross-site scripting execution will happen.

To check for this issue, one can follow below simple steps:

  1. Create any file, for example, a PNG file and name it with Cross-Site Scripting payload like the following: <script>alert(document.domain)</script>.png
  2. Navigate to the file upload functionality and upload this file and also capture the request with Burp Suite.
Original Request
----------------
POST /upload
Host: target.com
....
other headers
....filename=<script>alert(document.domain)</script>.png&data={file_content}

3. Once, the file is uploaded successfully, navigate to the endpoint that calls the files or stores the files.

4. If the application is vulnerable, a cross-site scripting payload will be executed.

There are certainly other ways such as using different file types, chaining file upload with CSRF to convert a self filename XSS to a good XSS, etc. that an attacker may attempt. However, the basic concept remains the same, just being creative is a plus in forming different scenarios.

CSV Injection

CSV Injection/Formulae Injection/CSV Excel Macro injection is a vulnerability that is often seen in the “File Export” functionality instead of the “File Upload” functionality. However, in the past, I have seen certain scenarios, where an application properly sanitizes the user-supplied input and doesn’t allow adding malicious payload even by performing client-side validation bypass, this results in blocking the attack.

However, if an application allows uploading a CSV file and if the content of the uploaded CSV file is not sanitized, i.e. the malicious payload contained within the CSV file is reflected as it is in the application. An attacker may attempt to upload a CSV file having a malicious command execution payload, that when exported by some other user, may result in successful execution.

To check for this issue, one can follow below simple steps:

  1. Upload a CSV file containing a malicious CSV Injection payload.
  2. Export the uploaded content by using any other user of the application.
  3. If the application fails to sanitize the user-supplied content while outputting the file, the attack may get executed successfully.

CSV Injection Payloads: https://github.com/payloadbox/csv-injection-payloads

Open Redirection

Open Redirection a.k.a Arbitrary URL Redirection is an attack that is generally seen on “Jump” endpoints, for example, an application while login, adds an additional parameter called “returnTo=/account” and this parameter may accept arbitrary URLs, ultimately resulting in an Open Redirection attack. However, this attack with the File Upload functionality is not widely seen or talked about but still possible to execute under specific conditions.

If an application allows uploading files such as HTML and the files are executed on the “Application Endpoint” itself [not downloaded and executed on the local system] but the execution of cross-site scripting is limited and it is not possible to execute any alert, prompt, confirm, etc. In such scenarios, it is possible to create a JavaScript payload that results in redirecting users to an attacker-controlled domain, an open redirection scenario can be crafted.

A similar scenario was observed in the following Edmodo Open Redirection through File Upload Proof of Concept: https://www.youtube.com/watch?v=FVeszzMJfpc

Server-Side Request Forgery

Server-Side Request Forgery is one of the very interesting and impactful security vulnerability. While, many people focus on looking for a callback or any similar endpoints that talks to internal/external endpoints to look for SSRF, the file upload functionality enables SSRF in multiple ways.

A file upload functionality that may allow the use of files such as HTML or SVG files, or allows uploading a file through a URL or through using various components as a part of restriction bypass can lead to an impactful Server-Side Request Forgery. It may be an Internal SSRF, Cloud Metadata SSRF or simply an External SSRF.

AWS Metadata SSRF via HTML File Upload: If an application allows uploading HTML file, however, doesn’t allow executing the javascript payloads, the attack scenario seems limited. However, if the HTML tags such as IFRAME are not restricted, it is still possible to upload an HTML file containing a malicious iframe code calling to the AWS Metadata Endpoint. Often this is not sanitized and blocked allowing an attacker to access AWS Metadata Endpoints.

Malicious Code
--------------
<body>
    <iframe src="http://169.254.169.254/latest/meta-data/" width="500" height="500"></iframe>
</body>

To check for this issue, one can follow below simple steps:

  1. Use the above malicious code and save it as an HTML file.
  2. Navigate to the file upload functionality and upload the HTML file.
  3. View the uploaded HTML file [assuming the file is loaded on the application’s endpoint only. For Ex: www.target.com/files/uploaded/ssrf.html
  4. If the application is vulnerable, observe that the AWS metadata information will be loaded in the Iframe.

Local File Read via SSRF in File Upload through URL: Many applications provide the functionality to upload files using a URL. However, if the application is not properly validating and restricting the internal/cloud metadata endpoints, an attacker may abuse this to read local files as well.

To check for this issue, one can follow below simple steps:

  1. Navigate to the application having the functionality to upload file via URL.
  2. Fuzz this endpoint with the “Internal SSRF Payloads List”.
  3. Observe if the application loads any local file.

SSRF Payloads List: https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Request%20Forgery

Blogs:

XML External Entities

Similar to the SSRF finding, the file upload functionality, opens the gateway for the XML External Entities, especially when the application accepts the file formats that support XML or when the file upload functionality itself uses XML to parse the data supplied by the user. In either of the cases, it is highly likely that the application will be vulnerable to an impactful XML External Entities issue.

XML External Entities through SVG File Upload: The SVG files supports XML and can help an attacker to construct a malicious SVG file in order to perform a successful XML External Entities attack.

Malicious Code
--------------
<?xml version="1.0" standalone="yes"?><!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/hostname" > ]><svg width="128px" height="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"><text font-size="16" x="0" y="16">&xxe;</text></svg>

To check for this issue, one can follow below simple steps:

  1. Use the above malicious code and save it as an SVG file.
  2. Navigate to the file upload functionality and upload the SVG file.
  3. Now, open the SVG file and if the application is vulnerable, contents of the file /etc/hostname will be displayed.

A lab explaining the above scenario is available on Portswigger Web Academy: https://portswigger.net/web-security/xxe/lab-xxe-via-file-upload

Note: if the simple XXE is not possible, an attacker may also attempt to perform an attack like SSRF through XXE or Out-of-Band [OOB] XXE.

XML External Entities in File Upload API: If an application utilizes SOAP APIs or use XML as a data type, it is still possible to perform an XML External Entities attack scenario. However, this is a simple scenario like other XML supporting endpoints where an attacker would attempt to utilize a malicious XML payload in place of the valid XML data and attempt to gain access to the sensitive information.

XXE Payloads List: https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20Injection

File Upload Bypasses

While the file upload related attacks are really wide, at the same time, modern applications implement a different degree of protection to mitigate or at least minimize the risk and likelihood of the exploitation. However, there are multiple ways to bypass the restrictions related to File Upload attacks. Some of the interesting bypasses are following:

  • Null Byte (%00) Bypass: It is possible to bypass the restriction on file upload bypassing a Null Byte in the file name, often with the extension.

Blocked File: test.html

Allowed File: test.html%00

  • Nth Extension Bypass: Using multiple levels of extension is one of the most common methods to bypass the file upload restrictions.

Blocked File: test.html

Allowed File: test.png.html // test.nothing.jpg.html

  • Content-Type Bypass: It is also possible to change the content type in order to mimic the malicious file as one of the allowed file extension types, resulting in bypassing the restrictions and uploading the malicious files.
Original Request
----------------
POST /upload
Host: target.com
....
other headers
....content_type=application/php&filename=test.php&data={file_content}

Now, by changing the content type to “image/png” an attacker may attempt to bypass the restrictions.

Modified Request
----------------
POST /upload
Host: target.com
....
other headers
....content_type=image/png&filename=test.php&data={file_content}
  • Magic Byte Bypass: It is possible to mimic a malicious file to look like a legitimate file. It can be achieved by adding magic byte header values to the content of the file. This bypass is effective when the application specifically checks for the Magic Bytes for validation.
    Reference: https://book.hacktricks.xyz/pentesting-web/file-upload#magic-header-bytes
  • Client-Side Validation Bypass: Sometimes an application only implements the restriction while uploading the file. This can be easily bypassed in a few steps.
    1. Change the file extension to accepted file extensions. For example, from .PHP to .PNG
    2. Upload the file and capture the request with Burp Suite.
    3. Now, change the file extension back to the original one i.e. .PHP and change the content type to “application/php” as well.
    4. Forward the request and if there is no server-side validation, the file will be uploaded successfully.
  • Blacklisted Extension Bypass: If an application is using a blacklist of extension, it is possible to bypass the restriction by trying for similar extensions.

Blocked File: test.php

Allowed File: test.php3, test.PhP, test.PHp

List of such extensions: https://book.hacktricks.xyz/pentesting-web/file-upload#file-upload-general-methodology

  • Homographic Character Bypass: Visually similar characters may fool an application’s logic and allow an attacker to bypass the restrictions. For example, an application doesn’t allow a ‘.php’ extension, however, a visually similar letter to “p” can be used to bypass this restriction.

Homoglyph/Punycode Generator: https://www.irongeek.com/homoglyph-attack-generator.php

Blocked File: test.php

Allowed File: test.php

Other References:

Misc. File Upload Attacks

While all the attacks that are discussed so far in the File Upload Attacks series are widely seen and are the most common attacks. There are many specific attacks and business logic abuse that may be seen in the file upload functionalities. Below are some of the go-to resources to look for:

Tools & Extensions

Tips & Tricks

  1. While testing a file upload functionality, enumerate all file extensions that can be used to perform attacks and list out all the allowed extensions.
  2. If an application is using an SVG/HTML file upload functionality, do not rush to report a less impactful finding, for example, reporting a Cross-Site Scripting without having any impact. Rather, explore this functionality and attempt for SSRF, XXE and other interesting attacks.
  3. Keep the mindmap handly and write down the workflow of your target application’s file upload functionality and try to figure out what can possibly go wrong. This always helps in finding Business Logic Flaws.
  4. Read lots of reports and blogs from other hackers around file upload attack bypasses to understand how to form various logics and possible scenarios to help in your situation.
  5. Keep on digging, file upload attacks are one of the most interesting parts of any target’s attack surface as mostly the files are stored on the application’s server [although many organizations are switching to cloud buckets & sandboxed environments] and chances of getting impactful findings are very high.

Remediation Plans

  1. Ensure that the file’s content is validated properly and input sanitization is performed.
  2. Make sure a strict check against file extensions is implemented and a whitelisted is used to allow only required filetypes.
  3. Make sure that the file size limit is properly validated and large files are not processed by the application.
  4. Ensure that the injection points such as filename parameters are properly validated and sanitized in order to prevent client-side and server-side injection attacks.
  5. A detailed remediation action plan can be found in the following article under Prevention Methods: https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload

End Notes

File upload attacks are very interesting themselves given their severity and depth of exploitation. We hope that you have learned something from this two-part series of File Upload Attacks blogs. We will keep on updating these blogs and mindmaps with the latest available information. Thank you very much for giving it a read.