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.
PHP is an interpreted language where a web server supporting PHP actually executes the content of a PHP file when loaded. If the BigCorp server was using PHP, Rachel could have gained remote code execution by uploading a PHP script.
Uploading dangerous files
- STEP 1
- STEP 2
- STEP 3
- STEP 4
- STEP 5
Setting the stage
Rachel, a software engineering student with a passion for hacking, has a grudge against BigCorp. She decides to poke around and see what she can do...
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.
Directory traversal + unrestricted uploads
Sometimes unrestricted file upload can be escalated by utilizing a directory traversal bug.
In the example of BigCorp, the
avatar.name variable is user supplied. A malicious file name such as
../../file.txt might result in the server storing the file at
/static/avatars/423543/../../file.txt, which translates to
/static/file.txt. Learn more about directory traversal vulnerabilities.
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 vulnerability in the code example above can be mitigated in the following way:
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
.docm would also not pass the filter.
Sometimes, this type of vulnerability allows an attacker to upload config files to alter the server policy. For example, on an IIS server, an attacker may be able to upload an ASP.NET
Test your knowledge!
Which approach should be implemented to limit the types of files that can be uploaded safely?
You have taken your first step into learning about the dangers of unrestricted uploads. You've learned how it works, what the impacts are, and how to protect your own applications. We hope that you will apply this knowledge to make your applications safer. We'd really appreciate it if you could take a minute to rate how valuable this lesson was for you and provide feedback to help us improve! Also, make sure to check out our lessons on other common vulnerabilities.