How can I determine a file's true extension/type programmatically?

前端 未结 11 1308
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-01 17:06

I am working on a script that will process user uploads to the server, and as an added layer of security I\'d like to know:

Is there a way to detect a file\'s true e

相关标签:
11条回答
  • 2020-12-01 17:28

    PHP has a superglobal $_FILES that holds information like size and file type. It looks like the type is taken form some sort of a header, not an extension, but I may be wrong.

    There is an example of it on w3schools site.

    I am going to test if it is can be tricked when I get a chance.

    UPDATE:

    Everyone else probably knew this, but $_FILES can be tricked. I was able to determine it this way:

    $arg = escapeshellarg( $_FILES["file"]["tmp_name"] );
    system( "file $arg", $type );
    echo "Real type:  " . $type;
    

    It basically uses Unix's file command. There are probably better ways, but I haven't used PHP in a while. I usually avoid using system commands if possible.

    0 讨论(0)
  • 2020-12-01 17:28

    Is checking the MIME type simply enough? I am assuming that changing the extension on a file doesn't change it's MIME type? Is MIME type a strong enough indicator to go by here?

    It really depends on how it's used.

    • If you provide uploads and downloads, then nothing matters since it doesn't execute.
    • If it's handled by the web server, then it's going to be dependent on how the web server is configured, though subject to most of the rest of these comments.
    • If it's an image, it will either display, or not, or be the target of image library exploits. But only those.
    • Something like a pdf file may not affect your server, but rather the computer of the person accessing the file.
    • If it's going to be passed to a function like "system()" then we're back to the OS behavior--as if it were "double-clicked", and the file extension might even be considered.
    0 讨论(0)
  • 2020-12-01 17:29

    PHP has a couple of ways of reading file contents to determine its MIME type, depending on which version of PHP you are using:

    Have a look at the Fileinfo functions if you're running PHP 5.3+

    $finfo = finfo_open(FILEINFO_MIME); 
    $type = finfo_file($finfo, $filepath);
    finfo_close($finfo);  
    

    Alternatively, check out mime_content_type for older versions.

    $type = mime_content_type($filepath);
    

    Note that just validating the file type isn't enough if you want to be truly secure. Someone could, for example, upload a valid JPEG file which exploits a vulnerability in a common renderer. To guard against this, you would need a well maintained virus scanner.

    0 讨论(0)
  • 2020-12-01 17:34

    What file types do you expect? Maybe you could check that it conforms to what you expect and reject everything else.

    0 讨论(0)
  • 2020-12-01 17:41

    Executables in general have a "signature" on the first bytes; I find it hard though to really ascertain what the file type really is.

    0 讨论(0)
  • 2020-12-01 17:45

    that could still be forged. I would ensure that you can not (or do not) run a file uploaded to the server automatically.

    I would also have a virus/spy ware scanner, and let it do the work for you.

    0 讨论(0)
提交回复
热议问题