I have a small web application. Because it is necessary to upload some files I check the file extensions with a whitelist (tgz, jpg, png, pdf, zip, rar, txt, gif, py, c, rb). In addition to that, I hash the filenames with md5 so e.g. when the user uploads the file "exploit.php.jpg" it is renamed to "526a8f9f3497b5a69bc4523ba0c6aacd.jpg".

There is neither a MIME-Type verification nor a "getimagesize()" or resize-function, if it is a picture. Because of that it is possible to upload a php-file that is just renamed to exploit.jpg

Although this seems to be very risky and the user also knows, where this file exists on my server (/images/526a8f9f3497b5a69bc4523ba0c6aacd.jpg), I am not able to run this file as a .php.

When I try to open /images/526a8f9f3497b5a69bc4523ba0c6aacd.jpg%00 or /images/526a8f9f3497b5a69bc4523ba0c6aacd.php and so on.. I only get "file not found" (.php) or "image can not be displayed" (jpg, gif).

Does anyone know if and how it is possible to exploit that fileupload?

  • 1
    py and rb? Do you have an interpreter that would execute these files? – KDEx Nov 18 '14 at 17:35
  • 4
    Have you considered null byte injections? Meaning upload a file called exploit.php%00.jpg? Personally I think you should read the first bytes of the file in order to determine the file header. File extension checking by itself is not sufficient enough in my humble opinion. – Jeroen Nov 18 '14 at 18:34
  • Have a look at how you can determine the file header: it.php.net/manual/en/function.finfo-file.php – Jeroen Nov 18 '14 at 18:44
  • @KDEx there is no python or ruby interpreter installed. When I try to open these files, my browser only offers to download these files – zarathustra Nov 18 '14 at 21:52

Don't trust a whitelist, it can be bypassed:

Content-type: image/jpeg; filename=exploit.php

Hashing the files does not protect you if the attacker can access the file direct:

<img src='http://yoursite.net/images/526a8f9f3497b5a69bc4523ba0c6aacd.jpg>

You could create a PHP script to read the file and send the contents to the user, unchanged. This way, the attacker will never reference the file on your server, and whatever server side exploit he could upload would not trigger:


$filename = getFilenameFromDatabase();
// e.g: $DOCROOT/images/exploit.rb.exe.py.bat.scr.php.jpg
header("Content-type: image/jpeg");

Just make sure to filter the path to the files, otherwise the attacker can get read access of your files.

  • Thank you for your answer. So the only way to use this vulnerability is, when I can manage to include the uploaded file in my php code? I tried <img src='exploit.jpg'> but nothing happend; only a "failed image" symbol is shown. – zarathustra Nov 19 '14 at 15:20
  • 2
    The whitelist bypass does not apply there. He whitelists the extensions, not MIME types, so your attack will not work. – v6ak Jan 17 '15 at 18:44
  • He didn't post the extension validation code so it may still be vulnerable to bypasses. – wireghoul Jan 28 '15 at 4:59

The file upload vulnerability could be exploited in combination with a local file inclusion bug to attack the server side. Or a malicious file (ie: pdf) could be uploaded to attack an end user with administrative privileges for example.

Your approach seems reasonable enough, however the devil is always in the details and you would need someone with security knowledge to take a look at your source code or running application for a more robust assessment.

  • +1 for out of box thinking. It works ! – Rahul Mar 21 '19 at 19:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.