views:

74

answers:

5
+3  Q: 

PHP Real file type

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.

+1  A: 

You want to look at MIME types. PHP's fileinfo extension is the preferred way to do this.

Kalium
+2  A: 

I would check this out:

http://getid3.sourceforge.net/

You can use this to validate that it's an audio file and get information about it.

Fosco
+5  A: 

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.

Pekka
+1 for getID3. I've used it before to check if a QuickTime movie contains streaming hints. Very, very useful.
Jon Cram
+1  A: 

Open the file after its been uploaded and check the first few bytes to see if it matches what should be in an mp3 file header.

GrandmasterB
first few bytes can also be ID3
Dan Heberden
I didnt say what the first few bytes could be, so I'm not sure how this applies to my answer. Are you sure you didnt mean this as a reply to one of the other answes?
GrandmasterB
+2  A: 

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

bobince
Yeah, I don't know. I always see how youtube let you upload anything but, if is not a video it says you "sorry". I think that I have pretty much the information I want. Thanks.
mRt