Hi all,
I'm working on a file upload script in which, for security reasons, I check if the file is allowed to be uploaded. I want to do so based on 3 - 4 checks.
First I check the file extension which is easy. But not very trustworthy. Who says I can't rename malicous_code.php to malicous_code.gif... :xbones:
So secondly I check the MIME type sent by the browser with the upload. This is given in the variable $_FILES['userfile']['type']. As the PHP manual mentions this isn't something you should fully trust because it isn't checked by PHP and thus is something one can manipulate. Besides I found documentation that MSIE bases the MIME info it sends in this variable on the file extension :xbones:
These checks complement each other. 1+1=3 in this case... If I were to just check the MIME things can go very wrong. Most images allow comments to be attached into them. So I could write malicious code to the comment of a gif and rename this image.gif to image.php. The MIME will still be image/gif eventhough the extension is php. It will pass the upload check and when the file is called with a browser the server will pass the file thru the php interpreter resulting into the malicious code in the image comment being run... :xbones:
Now if I were to just allow webimages for upload I could double check the MIME with getimagesize() and image_type_to_mime_type(). And I could strip the malicious code in the comment by recreating the image.
$size = getimagesize($_FILES['userfile']['tmp_name']);
if(!in_array(image_type_to_mime_type($size[2]), $allowed_mime)) {
//return error
exit;
}
$tmp_img = @imagecreatefromjpeg($_FILES['userfile']['tmp_name']);
if(!$tmp_img) {
//return error
} else {
imagejpeg($tmp_img, 'path/'.$_FILES['userfile']['name']);
}
But what if I do want to allow other MIME types? Like for uploading Adobe Illustrator files (application/postscript ai eps ps)?
I've tried the depreaceated mime_content_type() and it does the job for some MIME types but doesn't recognize a whole lot of others, for instance an illustrator.ai
mime_content_type($_FILES['userfile']['tmp_name']);
Why is this, or what am I doing wrong? Is it beacause the magic.mime file isn't up to date?
Ofcourse I should check the MIME with the fileinfo functions but I haven't gotten to that yet as I want to write this script to work on older server setups too.
Anyone know a way of checking the MIME type of uploaded files?
Cheers