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...