Link to home
Start Free TrialLog in
Avatar of ardasheks
ardasheks

asked on

preventing the passing of parameters with the URL

I've got a script that I want to prevent people from trying to hack into.  It processes an HTML form, I take the input using the param method.  The form is freely accessible by everybody, but I want to make sure that the only input the script can get is from the select boxes on the form.  How can I prevent people from trying to pass values with the URL, or how can I detect it if it happens, and handle it in the script?  Or is ther another way?
Avatar of ozo
ozo
Flag of United States of America image

Don't let your script accept any values that cannot be selected from your form.
Users can always generate a request containing any values they want.
ASKER CERTIFIED SOLUTION
Avatar of djsansui
djsansui

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Users can generate post requests too.  You cannot be assured that any parameters you see came from your form.  But if you reject anything that wasn't on your form then users cannot do anything that they could not have done from your form.
Avatar of kesonline
kesonline

Actually, I think you can do some sort of referer check to make sure it's coming from your page's address...rusty on Perl, I'll dig it up.
There's HTTP_REFERER (which is part of CGI, not part of Perl)
But users can send whatever they want for that too.
True, but much more of a pain to do. In the end, there's not much of a way. Perhaps you could use a hidden JavaScript to encrypt the values before sending or something such as that. Unfortuantely, I have no idea how to hide JavaScript, but I know it can be done.
If you send JavaScript to the user, the user can capture it and run it.
A one-way encryption may be able to give you the required security, but I don't see the point.
It makes more sense to me to distrust the source of any request, and simply not let the CGI program do anything that could not be legitimately done from the form.
One simple form of one-way encryption is table lookup.
If the CGI program has a list of select box values in the form,
the request need only tell the CGI which items in the list were selected,
and if the CGI only accepts items in the list, then it can only accept values that come from the form.
Avatar of ardasheks

ASKER

OK, what I'm hearing is

1) The only way to make sure that the parameters I get are not dangerous is to validate them in the CGI script.

2) Check the referrer to make sure the parameter came from my location.

Re #1:
GEEZ, I've got a select list with all the countries of the world, and
another that's almost as long!  Might be longer, actually. *So I gotta test for each one of those strings?*  Yikes!


Re #2:
It would make my form more useful if one or two of the parameters could be typed in by the user.  For instance, "city".  There are a heck of alot of cities.  That's one heck of a long select list..... maybe I could check for the most common type of hacking that would be done through that field (whatever that is).
#1, you must have a list of countries to generate the select boxes on the form.  You can use the same list to check the value you receive.

#2 Why do you care if anyone submits a non-city?   Depending on what you're doing with the value, it may be sufficient to check that it looks like a name, and not a command to format your disk and mail your password file to the user.
If you need to spellcheck for typos, or verify that the city matches the country, you may need to check a database anyway.
#1  This is how you can do it.  You can use this for whatever testing you want, if it isn't an acceptable answer, it will stop the script, and give an error.

@countries = ("place1",
"place2",
"place3");  #and so on, with all the country names,
                    #not hard at all.

$go = 0;

YA:foreach $i (@countries) { #check if it is an acceptable answer
 if ($country eq $i) { #make $country whatever variable you're using for it
  $go = 1;
  last YA;
 }
}

if ($go == 0) {&error;}
else {print "good";}

sub error {
print "bad country";
die;
}
#An easier way could be
@countries{
"place1" .. "place3",
} = ();

if( exists $countries{$country} ){
   print "good";
}else{
   &error
}