How to prevent HACKers from uploading fake Image Photos?

Hello,

What are the Php functions to call to make sure that a Photo that is being uploaded is an actual
(jpg, gif or png) image and not a Php function or other script or exe hacked as an image?

FYI, currently we are checking fro the following to make sure a file is being uploaded is a proper (jpg, gif or png) image:
1- Make sure file type is (jpg, gif or png)
2- Make sure dimensions are numbers
3- Make sure file size does not exceed allowed size

But somehow a hacker was able to upload Php, Php3, etc. files!

Thanks,
Dean.

Can you provide your code? I’d be curious to see what you have implemented thus far to see how it might be able to be bypassed.

Hello Cp,

Below is Php code we are using to check for proper image file uploaded.

if (preg_match('@^image/p?jpeg(;.*)?$@', $_FILES['uploadedfile']['type'])) {
				$filetype = 'jpg';
		  } else if (preg_match('@^image/gif(;.*)?$@', $_FILES['uploadedfile']['type'])) {
				$filetype = 'gif';
		  } else if (preg_match('@^image/png(;.*)?$@', $_FILES['uploadedfile']['type'])) {
				$filetype = 'png';			
		  } else {

				$error = 'Your selected Photo has the wrong file type. Acceptable image formats are either gif, jpg or png.';
		  }



	if ($_FILES['uploadedfile']['error'] == 2) {
			$error = 'Your selected Photo is too large. Maximum acceptable size is: ' . $max_q_foto/1000 . ' KB';
	}

Plus few other custom codes which for security reasons I cannot publicly share.

Thanks,
Dean

Can you be more specific as to what you mean by preventing people for uploading fake images?

There can be fake images like advertising on an image or do you mean someone uploading executable file as a jpg? If you want to check if an image is REAL and not some binary executable just simply do a color match. check if there’s colors in the file. :confused:

other things you can do is
exif_imagetype
mime_content_type
get_imagesize the list goes on.

Plus few other custom codes which for security reasons I cannot publicly share.

And where ever “Security” Code you have for images… i’m sure we already know it.

If you want better help, i recommend posting code.

Can you post more of your code? As what I’m not seeing is how you are detecting an error occurred and thus preventing the move_uploaded_file call to not be executed.

Yes, check to make sure that an image is really an image and not some files like:
.php, .php3, .tar, .txt
etc.

And the command we use for actually uploading the image file after all checks out is:

if ( (is_uploaded_file($_FILES['uploadedfile']['tmp_name'])) AND (copy($_FILES['uploadedfile']['tmp_name'], $target_path)) ) {

Okay, but I don’t see a check against $error, so you are telling it to copy the file regardless if $error is set? Thus allowing invalid files to be uploaded?

No of course not.
The $error check is done before the foto copy command is given.
And then we have another set of checking we do after the foto (file) is actually loaded onto the server.

So at either point I feel we need some absolute check on the file to be uploaded or already uploaded to make sure it is a valid image file only.

Has the OP read the SAitepoint article at http://www.sitepoint.com/handle-file-uploads-php/ which explains how to implement a number of security measures for file uploads including how to enforce that the file being uploaded is an image?

None of the solutions posted above will protect you from having anyone upload a “image” that is not an image if they really want to.

The problem lies in how the different methods detect if something is an image or not, read up on how they work internally and you will see that all that you need to do is add some code at specific places in the files.

What they will do, is give you an acceptable protection.

The key here is that for anyone to be able to “run” said code, there has to be a security vulnerability on either your code or the server. The way these “hacks” work is that they upload the “code” as a image, and then they use another security issue to change/execute the image file on the server.

With that in mind, I would not worry too much if someone upload an image that is not an image, as long as you make certain the rest of your system is secure, all you need to do is use some of the available options to check if a file “look like” an image and you are good.

Note. that this will not stop anyone from uploading images that contain trojans or virus, but those would affect visitors and not server side as I understand you have problems with.

Yes, we are of course aware of the information listed here:

since these are rather elementary, and necessary, intel about file uploading via Php.

So presumably you implemented the code provided on that page for checking that the file uploaded is a genuine image file.If so then why are you asking here how to do what that page already covered.

Well you are assuming that that page has covered all that there is to cover about preventing HACKERS from uploading fake files. It is obviously has not. And thus the reason for the question posted. Again, the page you are referring to has important must use information but it is just the basic of what needs to be done to prevent determined and resourceful HACKERs from uploading malicious files.

Sorry, I posted the wrong link - the SitePoint page I meant to link to was http://www.sitepoint.com/file-uploads-with-php/ which has a section on security with specific code on validating that a file is an image.

Thanks for this new link.
I have to read through it carefully. Cannot now since something else urgent has come up.
Will let you know ASAP.

I know this won’t necessarily answer your specific problem, but a good way to prevent “PHP images” to be “executed” is to have images served from a place that doesn’t execute PHP scripts. It could either be an external CDN or just a simple directory . I think you can achieve that by adding a .htaccess with this code in the desired directory:

php_flag engine off

Just be careful that people can’t upload a .htaccess over it or in another sub directory to change the behavior.

While it is a good idea, it does not really add any additional protection.

First off, your web server will not execute any php code inside an image file. The file will be passed directly to the user accessing it as it is a static file.

This means that to be able to use the code inside on of these uploaded images, the hacker need to have another access point as well. Normally this is another vulnerability in the website scripts, or a hole in the OS security. By using this hole, they then either include the file through another system on the server (and by that it is executed as text + php code), or they rename the file so it can be executed directly.

Either way, with both of these the .htaccess protection would be void. The first due to they dont run the file directly, the second due to if they can rename the file, they can also remove the .htaccess file.

Note. Assuming the “image upload script” at least deny the upload of any other extensions than the allowed image types.

If we take a look on enterprise systems, the way this is normally handled is that images etc. resident on a static server cluster (+ possible CDN in addition). This way the file can never be accessed to do anything malicious on the servers.

Another solution often used, is that the “public” accessible servers only connect to the API servers, this way no code is executed directly on the web servers except for the calls made to the API servers. Note. this is also normally tied together with static servers, but you could also feed the images back to the public web servers if you run on a small scale, since the code your securing on the servers would be very little. (meaning very low risk of a security vulnerability that could cause an issue)

Thanks for the clarification. So, it could prevent some “problems”, but it’s not everything.

Don’t get the “type” of the file from HTTP headers. Those can be changed and the post may not come from your form. Use string functions to get the file extetension and derive your “type” from that, not from the incoming upload. Your web server is going to treat that file in the way it knows to treat it’s three digit extension. You can certainly check for size or the presence of PHP tags in a file with a jpg, gif or png file extension that is uploaded, but just as with everything else do not trust input from outside your app. That includes any information sent by the browser. Everything in the $_FILES array is provided by the user agent which could just as easily be curl set up by a hacker to give you false file type information.

Don’t rely on the extension - it is even easier to fake than the MIME type.

The SitePoint article suggests using exif_imagetype to test if the file is an image. That function will reject any file that it can’t recognise as a valid image.