An upload functionality on a website can potentially raise many issues. If it is not implemented correctly , attackers could upload malicious files to the server.
Impact
Depending on what the server does with the uploaded file, the consequences of the file inclusion bugs can vary a lot. Generally there are two types of file inclusion bugs.
- File meta-data bugs
- File content bugs
File meta-data bugs
These bugs are caused by the files meta-data such as the path, the file name, hidden EXIF data, …
- Check if the original filename is changed, if not check if there are filters in place. This could lead to XSS.
- What happens if you change your filename to
../../evil.php
, is directory traversal possible? - Is EXIF data stripped from the files? Try implementing payloads into the meta-data. It may not cause problems now, but maybe in the future.
Here are some other great examples on how to use file upload to achieve XSS.
File content bugs
Bugs of this type are caused by the files content, size, …
- If there are no restrictions on upload, an attacker could upload a webshell and execute code on the webserver
Example of a webshell:<?=`=$_GET[x]`?> http://domain.com/uploads/webshell.php?x=cat%20%2Fetc%2Fpasswd
Which will in turn execute the following code on the web server:
cat /etc/passwd
- If there are restrictions in place, you should try to find out which file types are accepted. You could also try to change the MIME type.
Example:
The site example.com has a functionality where a user can upload a profile picture. An attacker could try to upload a html file disguised as an image.
More information on MIME types. - Some filetypes can contain malicious content. Here is an example on how to hide Javascript in a png image.
- Check if there is a limit to the maximum size of uploaded files, this might cause Denial of Service.
How to defend against File Upload Attacks?
The type of attack really depends on what the application does with the uploaded file, so there is no one way to defend against every type of attack. But there are a couple of things you can do.
- Don’t use the provided filename from the user, generate your own filename. User input should never be trusted in general.
- Set a limit on the size of the files.
- Strip EXIF data from files it could hide malicious user data.
- Use a whitelist for the MIME types which are accepted. (Blacklisting is not a great idea as this can be bypassed, it is easy to forget certain )
- Use separate domains. Store user files on a different domain so if JavaScript should be executed, same-origin policy will come into play.