Validate uploaded files with getID3()

The place for "I can't figure out how to..." questions.
Post Reply
WaldoMonster
getID3() contributor
Posts: 108
Joined: Mon Apr 01, 2002 12:20 am
Location: Netherlands
Contact:

Validate uploaded files with getID3()

Post by WaldoMonster » Sat Jul 29, 2017 8:37 am

Is getID3() the appropriate tool to validate uploaded audio and or video files?
I want to only allow audio and or video files an prevent for wrong renamed extensions.
Is it enough to check the existence of the video and or audio root tag?

Thanks,

Willem

WaldoMonster
getID3() contributor
Posts: 108
Joined: Mon Apr 01, 2002 12:20 am
Location: Netherlands
Contact:

Re: Validate uploaded files with getID3()

Post by WaldoMonster » Sat Jul 29, 2017 11:10 am

I was thinking to use something like this:

Code: Select all

$getID3->analyze($_FILES['media']['tmp_name'][$i]);
if (isset($getID3->info['error']) || (isset($getID3->info['audio']) == false && isset($getID3->info['video']) == false)) {
	// Error message
}

James Heinrich
getID3() v1 developer
Posts: 1435
Joined: Fri May 04, 2001 4:00 pm
Are you a spambot?: no
Location: Northern Ontario, Canada
Contact:

Re: Validate uploaded files with getID3()

Post by James Heinrich » Sat Jul 29, 2017 12:55 pm

That would generally work great. Anything that gets through that should reasonably-certainly be a proper audio/video file.

With one exception: MP3

MP3 is a fine format whose popularity has led to an unfortunate amount of corruptions and nonsense. Since it's a bitstream format, you can throw whatever garbage you want anywhere into the file (including the beginning) and by standard the player simply skips anything it doesn't understand (on the assumption it's a transmission error). Indeed that's how ID3v2 is allowed to be at the beginning, and ID3v1/APE/Lyrics3 at the end (the mpeg-audio bitstream format has no native support for metadata).
So it is theoretically possible to have a small executable of some kind, appended with MP3 audio, and named .mp3 that could pass your above test (it would also play fine in Winamp or any other audio player). This would be a specially crafted attack, so not something I would expect to run into, but it's possible.

You can adjust GETID3_MP3_VALID_CHECK_FRAMES in module.audio.mp3.php down to zero to disable the skip-invalid-audio-data-in-mp3 feature. That should remove this potential attack vector (but a lot more playable MP3s may scan up as invalid).

WaldoMonster
getID3() contributor
Posts: 108
Joined: Mon Apr 01, 2002 12:20 am
Location: Netherlands
Contact:

Re: Validate uploaded files with getID3()

Post by WaldoMonster » Sat Jul 29, 2017 2:20 pm

Thanks very much for the clear answer James!
I amuse it is not possible to define('GETID3_MP3_VALID_CHECK_FRAMES', 0); outside getID3() because it will be overwritten by the module.audio.mp3.php script.

James Heinrich
getID3() v1 developer
Posts: 1435
Joined: Fri May 04, 2001 4:00 pm
Are you a spambot?: no
Location: Northern Ontario, Canada
Contact:

Re: Validate uploaded files with getID3()

Post by James Heinrich » Sat Jul 29, 2017 3:18 pm

Once a constant is defined it cannot be changed, so if you pre-define it outside module.audio.mp3.php you'll get a PHP Notice:

Code: Select all

Notice: Constant GETID3_MP3_VALID_CHECK_FRAMES already defined in <file> on line <line>
but the constant will retain whatever value you set first. You could of course edit module.audio.mp3.php and wrap the define line in an !if_defined check:

Code: Select all

if (!defined('GETID3_MP3_VALID_CHECK_FRAMES')) {
	define('GETID3_MP3_VALID_CHECK_FRAMES', 0);
}
which would let you define the constant outside getID3 without generating errors.

WaldoMonster
getID3() contributor
Posts: 108
Joined: Mon Apr 01, 2002 12:20 am
Location: Netherlands
Contact:

Re: Validate uploaded files with getID3()

Post by WaldoMonster » Sat Aug 05, 2017 10:31 am

Thanks again James!

Post Reply