Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP Real file type [closed]

I am building a website where the user can upload mp3 files. And, I want to check if the file is a mp3 file. What I need to know is if there is a php function that do that for me.

I tried $_FILES['uploadedfile']['type']

But, I does not work like I want, because it returns the file type based on the extension (I tested it only on windows)

So, the questions are:

  1. There is a safe way to do that with php native functions??
  2. The file type based on extension, is a php issue or is related to the OS?
  3. What do you recomend to me??

Thanks.

like image 778
mRt Avatar asked Jul 09 '10 20:07

mRt


2 Answers

1- There is a safe way to do that with php native functions??

For MP3s, not with PHP native functions, no.

There is fileinfo that makes use of the OS's "MIME sniffing" functionality. If installed, it's usually pretty reliable.

Alternatively, the getID3 library claims to be able to extract information from MP3 files. If you can get a playing time from the file, chances are it is a valid MP3 file.

2- The file type based on extension, is a php issue or is related to the OS?

Neither. The browser determines the file type (according to extension usually) and sends a MIME type. As with any incoming data, it is very easy to fake and can never be trusted.

like image 147
Pekka Avatar answered Oct 03 '22 14:10

Pekka


The question of what an MP3 is is a bit woolly. MP3 files typically contain a bunch of chaff at the start and/or end that's not valid MP3 frames. Usually this is for holding ID3 tags, but it's not uncommon to meet MP3s with nonsense data at the ends for other reasons (eg. naïve stream chopping).

In practice almost anything can be an MP3, and many arbitrary binary files will have something that looks like an MP3 frame in it. Looking for ID3 and length information (as in Pekka's answer) is a good heuristic approach to get an idea if a file is likely to be MP3, but that's not sufficient if what you have in mind is security-related.

it returns the file type based on the extension (I tested it only on windows)

Actually it returns the type string the user's web browser sent it, which on Windows will be determined by the original file extension, but on Mac or Linux may come from other sources. Either way, like the filename itself, it's not to be trusted. The user's computer may be set up wrong or may be deliberately sending the wrong media type string for a file.

There is a safe way to do that with php native functions??

What is your intention with ‘safe’? If your aim is to stop people uploading MP3 files that are actually other filetypes in disguise—typically for the purposes of injecting HTML, Java or Flash content for cross-site-scripting attacks—then there's no realistic way to do this. You can make files that are valid MP3s and yet also may be interpreted as another type at the same time. (See ‘GIFAR’ attacks; the same is possible with MP3.)

In the end the only approach that reliably protects you from XSS attacks is to serve untrusted user-uploaded files from a different hostname that shares no security context with the main site, so cross-site-scripting into it gains nothing. A partial solution you can also consider instead or as well is to serve all your files with a Content-Disposition: attachment header (if you don't need to host images that'll be displayed inline in a page).

like image 41
bobince Avatar answered Oct 03 '22 14:10

bobince