When handling uploaded files $_FILES['foo']['type']
is not at all reliable. I've found if you change the extension on OS X the 'type' is changed automatically.
Instead consider:
$fileInfo = new \finfo(FILEINFO_MIME);
$mimeType = $fileInfo->buffer(file_get_contents($_FILES['foo']['tmp_name']));
$mimeType = explode(';', $mimeType);
Now, if I rename a PHP script to .jpg and upload it (on OS X 10.10) $_FILES['foo']['type']
= image/jpeg
and $mimeType
= text/x-php
.
The file type can easily be changed but how can PHP's finfo::buffer be spoofed? What is the difference between what PHP checked for $_FILES['foo']['type']
and finfo(FILEINFO_MIME)
?
PHP doesn't check anything in the $_FILES
type; when uploading a file, the sending browser is sending meta data of what it thinks the file type is. $_FILES['file']['type']
simply reflects this value uploaded by the browser. Obviously, anyone can spoof this at will.
Finfo uses the magic database, which is simply a collection of identifying characteristics of file types. I.e., all JPEG files have a characteristic header, all ZIP files start a certain way, this file type has these number of leading bytes, that file type has those kinds of trailing bytes etc. etc. This is harder to spoof, if you actually want to produce a valid file of a certain type, but by no means impossible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With