0

Within a form, I need to validate that the file uploaded has an MP3 file format (without using a framework).

I am choosing to validate the upload using the more secure fileinfo method as opposed to a simple file extension check.

The problem I am incurring is that when a legitimate MP3 file is submitted to the form for validation, the MIME type ($mime_type) returned from the MP3 file is application/octet-stream. This is a generic fallback for unknown/generic MIMEs and it doesn't work with a MP3 validation script like so:

// Simplified Version of The Code
// ... File info resource is already opened

if($mime_type == 'audio/mpeg') {
    echo '<p>Correct MIME Type</p>';
} else {
    echo '<p>Incorrect MIME Type</p>';
}

The code above returns "Incorrect MIME TYPE" for a real MP3 file. This is because the file is portraying as application/octet-stream.

Dharman
  • 30,962
  • 25
  • 85
  • 135
array_map
  • 1
  • 1
  • have you try to print result of `$mime_type`? – Simone Rossaini Aug 09 '22 at 09:39
  • Yes, I have. $mime_type when printed returned with a value of application/octet-stream. – array_map Aug 09 '22 at 09:42
  • Thanks for the link. The answers there don't provide a standard solution to this problem. Does PHP not have an in-built way to securely and reliably check MP3 files? – array_map Aug 09 '22 at 09:52
  • The most reliable way to check if a file is a real mp3 is to use ffprobe to integrate the file, obviously depends on the server/hosting environment you have at you're disposal if you can do this. If not the 'loose' checking of mimetype is best you can do, but note, it can be easily spoofed. – Brian Aug 09 '22 at 09:58
  • Please read the answer from the link: _All this boils down to that identifying an MP3 by using PHP's fileinfo and the like isn't reliable, as the actual MP3 data can start ANYWHERE in a file. fileinfo only looks at the first kilobyte or two of data, so if it says it's not an MP3, it might very well be lying because the data started slightly farther in._ – Simone Rossaini Aug 09 '22 at 10:01
  • Assuming you can, you would exec(), something like: ffmpeg -i foo.mp3 ... See ffprobe's documentation if you go this route for what it returns. – Brian Aug 09 '22 at 10:01
  • Perhaps it would make sense to already check this on the client side? I suppose most modern browsers can play mp3 files - so you could probably grab the file content & transform it into a data URI. Assign as source for an `audio` element (muted), and then see if events like `canplay` or similar fire ... – CBroe Aug 09 '22 at 10:28
  • Thanks Simone. As I had previously stated, it seems that PHP doesn't have a standard solution (no in-built function) to to securely and reliably check MP3 files - I would have to find a way to check where the MP3 data starts. – array_map Aug 09 '22 at 10:30
  • Thanks Brian. I'll find out more about ffprobe and whether my hosting environment will allow for this. – array_map Aug 09 '22 at 10:34
  • Thank you CBroe. I could try validating this on the client-side as an extra layer of security but with keeping in mind that client-side validation can be disabled by a malicious user. – array_map Aug 09 '22 at 10:40
  • A file having an extension `.mp3` doesn't mean it's an mp3 file. – Dharman Aug 10 '22 at 16:11
  • @Dharman I had previously recognized file extension checking as insecure in my question. – array_map Aug 11 '22 at 06:01

0 Answers0