Unrestricted upload of files with dangerous types
File upload functionality can present a huge risk to your application if implemented incorrectly!
Select your ecosystem
What is unrestricted upload of file with dangerous type?
An unrestricted upload of files vulnerability occurs when an application performs insufficient filtering — or lacks filtering entirely — when accepting file uploads.
Unrestricted upload of file with dangerous type can come in many shapes and forms. Uploading a JPG file will not do much, but uploading a PHP file onto an Apache server with PHP enabled may result in remote command execution. A threat actor may also abuse this vulnerability class to host malware or illegal content.
About this lesson
In this lesson, you will learn about vulnerabilities stemming from unrestricted upload of file with dangerous type and how to protect your applications against them. We will step into the shoes of a troubled youth who holds a grudge against BigCorp and a penchant for hacking.
Let’s break down what happened in the story above.
- Rachel was able to upload all kinds of files via the avatar endpoint, instead of just images
- Some file extensions trigger different behavior on the server or in a browser. She was able to exploit this and upload an HTML file containing malicious code
Because the avatars are in a public folder (/static
), she could visit the uploaded file and share this location with others. The code that BigCorp used for the avatars upload is:
The backend code does not apply any filters when processing the file. It takes in the file and the filename from the request and uses those to store the file on the server.
What is the impact of unrestricted upload of file with dangerous type?
The impact varies based on several factors. The most important two are:
- Are the uploaded files accessible? For example, via the
/static/
folder on the web application - What is the backend using? For example, the impact with NodeJS is limited because you can not get a file to execute, unlike other languages or frameworks such as PHP
Given that the uploaded file is accessible, such as in the scenario of BigCorp, and the backend is using NodeJS, then an attacker can host malicious files on the server, and perform stored cross-site scripting attacks.
The term "malicious files" encompasses many different file types, not just server-side scripts. It could be malicious .exe files, Microsoft Word documents with malicious macros, ransomware, spyware, etc.
Another common scenario is when an attacker wants to phish a victim with a Word document that contains a macro. The attacker may use a vulnerable file upload function to get the malicious Word document onto the victim's computer, and then just link to the document in a message.
Some general advice when creating file uploads:
- Decide what kind of files you want to allow and deny
- Implement allow lists instead of deny lists (deny lists tend to be easier for an attacker to bypass)
- Generate file names yourself
- Uploaded files shouldn’t be publicly accessible unless really needed. Even then, try to implement proper authorization to ensure only the right people have access to them
The fileupload
package in NodeJS has an option to strip a set of characters from the filename and make it safe. This option is by default set to false
but can be enabled in the following way:
The backend can then force the extension to be .png
at all times:
This might seem like a good approach, but actually in the example of avatars, there is no need to preserve the original filename. It is a safer approach to generate a random filename:
While this might be a safe approach, it’s still not ideal because it disregards the original file extension, which could have been a different image type, such as JPG or GIF.
A very simple approach to an allow list type of filter, combined with generating a random filename, is the following:
This extracts the file extension and only continues if it is included in the allowed extensions list, defined in an array.
In the example of Rachel and BigCorp, where Rachel would try to upload an HTML file, the upload would fail because html
is not included in the allowed extensions list. Other extensions such as .exe
or .docm
would also not pass the filter.
Test your knowledge!
Keep learning
Check out these links to learn more about this vulnerability:
- Unrestricted upload of file with dangerous type is a CWE. More about this can be found at the official MITRE website
- The Open Web Application Security Project has a large section on unrestricted file uploads