views:

50

answers:

3

Hi

I have a PHP app which takes a user-inputted $imageurl and does the following:

exec('convert "'.$url.'" -thumbnail 80x500 "images/out.jpg"');

Now obviously I have to take some precautions with this to stop users from executing arbitrary code. For example, if the user sets $url to";rm -rf *;" is no good at all.

So for starters I have to filter out " so that no matter what they type in, they can't escape from their input being a parameter to convert. But should I filter out ; as well? I've seen urls with semicolons in them... and while the semicolon is really the danger here, filtering out " would still keep me safe right? But can urls have " in them? And are there any other characters I should watch for?

Maybe instead of filtering characters out I should try to escape them. So should I try to escape every character interpreted specially by the shell? Or just escape " as everything else is sort of "pre-escaped" given that it's inside double-quotes?

Sorry for my rambling confusion, I'm just new at this and want to stay safe!

Thanks,
Mala

+3  A: 

Well, if you want to make sure the URL is a URL, use filter_var

filter_var($url, FILTER_VALIDATE_URL);

This will not prevent people from supplying a URL like example.com/foo?;rm -rf though, which is still a valid URL. I'm not sure if this would cause rm to execute, but you could also check the URL with parse_url() and omit the query part.

Generally, it is a good idea to have a look at these as well:

Also see the PHP Manual on securing user input.

Gordon
I can't omit the query part as some sites serve there images via script.php?image=something.jpg
Mala
Then just use filter_var and the shell escape function
Gordon
+2  A: 

You can use the escapeshellarg function.

klausbyskov
A: 

Use Regular Expressions to ensure that $url only contains valid filename characters, e.g. "(\w\.\-\/){1,256}". Plus, I imagine you are renaming the file the user uploads to be a random filename, or at least a whitelisted filename (i.e. using the same regex). sha1.ext or md5.ext are easy formats to use.

Mike