0

I'm facing an issue with file uploads using Yii2 framework, but I think that question goes deeper than a framework problem. I have an app that allow the user do pdf files uploads, until here my app works fine but I'm in trouble when some smartass rename the filename extension from anything to pdf. The app isn't validating this kind of trick.

I tried without success to validate the mimetype. Now I'm looking for another way.

Anyone know how to block this kind of cheat?

Cœur
  • 37,241
  • 25
  • 195
  • 267
  • 1
    Possible duplicate of [how to check the uploaded file type is pdf](http://stackoverflow.com/questions/11039095/how-to-check-the-uploaded-file-type-is-pdf) – dev0 Jan 05 '16 at 11:24
  • 1
    The most reliable way is to open the file in a php pdf library and then save it to the new location - if it is not a pdf file, the pdf reader will fail / throw an exception. This is a lot more work than just checking the mime type though (as mentioned in the above linked question by @dev0 ) – Steve Jan 05 '16 at 11:29
  • @dev0 isn't working for me. The app keep uploading. – Thiago Augustus Oliveira Jan 05 '16 at 12:06
  • @Steve I was afraid to hear that. This change will do the process to the user harder. – Thiago Augustus Oliveira Jan 05 '16 at 12:08
  • It will certainly be more work for you, but the user shouldnt notice really - it will be a bit slower, but i guess this is done async (eg ajax) anyway, so an extra second or so seeing a progress bar reading `Verifying file type' wont make much difference – Steve Jan 05 '16 at 12:12
  • @Steve this change will also worse the performance of the app. Everyday I got thousands of uploads. But if I don't find otherway it will be something that will have to bear. – Thiago Augustus Oliveira Jan 05 '16 at 13:29
  • You said `finfo` isn't working for you... but what it's returning? It's saying the file is an "application/pdf"? It's triggering an error? Returning empty? – Clyff Jan 05 '16 at 14:10

3 Answers3

1

Its better to keep it simple and just use this

<?php 
$finfo = finfo_open(FILEINFO_MIME_TYPE); 
if(finfo_file($finfo,$filename) == 'application/pdf'){
    // input file is pdf
}
?>

Since you said its not working for you you can try these

if you are using a Linux server you can use the shell commands to check them mime type

<?php
function detectMimeType($filename='')
{
    $filename = escapeshellcmd($filename);
    $command = "file -b --mime-type -m /usr/share/misc/magic {$filename}";

    $mimeType = shell_exec($command);

    return trim($mimeType);
}
?>

Or you can try this method .Here we assume that Pdf file starts with a %PDF string .[usually it does start with %PDF].

<?php
function detectFileType($filename='')
{
    $handle = fopen($filename, "rb");
    $contents = fread($handle, 4);

    fclose($handle);
    if($contents == "%PDF")
    {
        return "application/pdf";
    }
    else
    {
        return "application/octet-stream"; //unknown type
    }
}
?>

[this code is not tested ]

Refer these links you will get some more info about what went wrong

http://php.net/manual/en/function.mime-content-type.php

http://php.net/manual/en/ref.fileinfo.php

Midhun
  • 3,850
  • 1
  • 23
  • 26
0

the best way is to check mime type of file :

http://php.net/manual/en/function.finfo-file.php

<?php
$finfo = finfo_open(FILEINFO_MIME_TYPE); 
if(finfo_file($finfo,$filename) == 'application/pdf'){
    // input file is pdf
}
finfo_close($finfo);
?>
Saeed M.
  • 2,216
  • 4
  • 23
  • 47
0

The problem was solved using the mime_content_type function.

Check the function here php.net

This function returns the real mime type.