How to read header of a file uploaded in PHP?

11,806

Solution 1

Try finfo_file(). You have to call it passing the filepath. Example:

$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $_FILES['control_name_from_client']['tmp_name']);
finfo_close($finfo);

You need the Fileinfo extension. As PHP manual says:

The functions in this module try to guess the content type and encoding of a file by looking for certain magic byte sequences at specific positions within the file. While this is not a bullet proof approach the heuristics used do a very good job.

Solution 2

There used to be the mime_magic extension in older versions of PHP, but that's deprecated now in favour of finfo_file, which does use file signatures to test the filetype, not purely the extension.

Solution 3

as far as I'm aware, there is no such function in PHP, but if you have access to the CLI (and are running Linux), you could use the "file" command through system().

Solution 4

Dunno what "header" you are talking about, but from the security point of view the only thing you really have to pay attention to is a filename extension.
Just because your web-server would judge your file by it.

To test if uploaded file being valid data for some particular application, you have to use this application-specific routine, there are no universal tool in PHP. you can use imagemagick for images, getid3 for the mp3 files, fffmpeg for the movies and so on.

But of course whole file have to be employed, checking just "header" doesn't guarantee that entire file is valid.

Share:
11,806

Related videos on Youtube

Kumar Kush
Author by

Kumar Kush

Updated on June 04, 2022

Comments

  • Kumar Kush
    Kumar Kush almost 2 years

    Can we read the header information of a file in PHP to determine the type of file uploaded?.

    I don't want to rely on $_FILES['control_name_from_client']['type']. As we know that this property determines the file type by reading the extension of the file uploaded.

    What if the user renames, say test.jpg -> test.xls. In that case, $_FILES['control_name_from_client']['type'] will show the type as application/vnd.ms-excel instead of image/jpeg. It is but natural this can create problems if a code has to be executed which reads the XLS file to fetch data for some processing.

    Any suggestions please?

  • Kae Verens
    Kae Verens over 12 years
    mime_content_type() bases its result on the extension. not sure about finfo_file()
  • lorenzo-s
    lorenzo-s over 12 years
    @Kae: You are right. I think the Fileinfo extension is clever.
  • Kumar Kush
    Kumar Kush over 12 years
    You are right that checking just "header" doesn't guarantee that entire file is valid, but it does ease the things a bit more, if not to the fullest.
  • Kae Verens
    Kae Verens over 12 years
    not good enough. example: upload a PHP file named "test.php.blah" - a default Apache+PHP installation ignores the ".blah" and treats the file as a PHP file. You cannot rely on the extension.
  • Kae Verens
    Kae Verens over 12 years
    @Col.Shrapnel verens.com/2008/10/13/… <-- how I found out about it. basically, a default Apache installation treats files with multiple extensions as if the end extension is a language (for example, index.html.en), but it doesn't check to see if it's a /real/ language. so you could upload a PHP script disguised as an image (index.php.jpg) and it would run as a PHP script.
  • Your Common Sense
    Your Common Sense over 12 years
    @KaeVerens well, with .blah it is possible. with .jpg - no. Just check your extensions like I said.
  • Kae Verens
    Kae Verens over 12 years
    wrong. just try it and see. create a file on your webserver called "test.php.jpg", containing "<?php phpinfo(); ?>" and view it. if you're right, it should appear as either a broken image, or plain text. if I'm right (and I just tested this, by the way...) it will run the phpinfo() function.
  • Your Common Sense
    Your Common Sense over 12 years
    @Kae Well, you are right, my apologies. The behavior looks insane.
  • Bhavik Shah
    Bhavik Shah almost 8 years
    @KaeVerens I think, the behavior you have noticed has been rectified now. I have followed the exact steps as you have suggested. But, thank god, it doesn't ran phpinfo(). Instead, it displayed broken image. I will surely like to know if I have missed something or if you can still reproduce the issue somehow.