Page 2 of 2

Re: basename secure for path injection?

Posted: Mon Sep 22, 2008 2:03 pm
by allicient
Eh, there is a simple (and probably provably) secure way to do this. Use a hash table.

All PHP arrays are associative arrays anyway (i.e. a hash table) - which makes this solution even easier with PHP.

Just declare something like:

$valid_paths = array( 'expected/web/path/1' => '/home/www/real/path/1', 'expected/web/path/2' => '/home/www/real/path/2' );

(change and add elements as required obviously)

and when you come to check things:

if ( array_key_exists( $_GET[ 'path' ], $valid_paths ) ) {
$path = $valid_paths[ $_GET[ 'path' ] ];
} else {
$path = '/path/to/some/error/message/or/default/';
}


that way you don't have to worry about the security of basename(), nor have to design a decent regex which can be tricky at best.

If maintaining $valid_paths is difficult, you could store it in db table which would make it easier to modify from an admin interface or whatever.

Regards,

Peter

P.S. I haven't touched PHP in a while so my syntax may be a bit iffy, but you get the idea.

Re: basename secure for path injection?

Posted: Mon Sep 22, 2008 3:32 pm
by matthijs
Maugrim_The_Reaper wrote:I wasn't referring to basename() being insecure in and of itself - merely that using it in isolation without supporting measures does in some circumstances lead to vulnerabilities. It's more a comment on the level of faith some developers put in native PHP functions, or rather their misinterpretation of those functions. basename() doesn't return a filename, it returns a string that passes for a valid system filename. That's a subtle distinction.
Thanks for the clarification.

You make a good point. But it's good to know why exactly you have your reservations. There's a difference between a function not doing what it is supposed to do and not using it correctly.

Re: basename secure for path injection?

Posted: Mon Sep 22, 2008 4:56 pm
by josh
Ok yeah, by valid file name I meant syntactically valid, not semantically valid. Obviously the function needs to be used properly, but you can rely on it for it's intended purpose.

And escaping strings to be used as a filename and escaping a string for output are 2 entirely different things, a subtle distinction in it's own... If all you need to do is make sure the user hasn't appended any paths, you can rely on basename and using regex would be re-inventing the wheel, but like you said you can't just blindly rely on it to do things it wasn't meant to do, if you need to make sure the "filename" matches a pattern, then regex would be a good solution.. and like you said using both regex ontop of basename() would be pointless unto itself