?
Solved

preventing the passing of parameters with the URL

Posted on 1999-11-17
12
Medium Priority
?
187 Views
Last Modified: 2012-05-04
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?
0
Comment
Question by:ardasheks
  • 7
  • 2
  • 2
  • +1
12 Comments
 
LVL 85

Expert Comment

by:ozo
ID: 2216061
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.
0
 
LVL 2

Accepted Solution

by:
djsansui earned 200 total points
ID: 2218384
I think what your trouble is is that you are using the "get" method.  this makes the script get the values from the string in the URL such as script.pl?value=forty-two

You should use the post method for your form, it is more secure because the user cannot see the data that is being passed to the script, the data is not saved in the browser's history folder, and there is no way for someone to pass other values to the script from the URL.  The perl code to get data from the post form method is this:

read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
    ($name, $value) = split(/=/, $pair);
    $value =~ tr/+/ /;
    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
    $FORM{$name} = $value;
}

The other thing you should do is to prevent users from copying your HTML form and making their own.  This is accomplished by one of two methods.  One, as Ozo suggested, have any content that you want to limit as radio buttons, checkboxes or drop-down menus, and then within the scipt, check that the value matches one of the possibilities that you want to limit it to.  The other way to do it is to check that the $ENV{'HTTP_REFERER'} exists and is the location where your form is.

If you use these methods in conjunction with each other, you will effectively eliminate your hacking worries.
0
 
LVL 85

Expert Comment

by:ozo
ID: 2218479
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.
0
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
LVL 1

Expert Comment

by:kesonline
ID: 2221338
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.
0
 
LVL 85

Expert Comment

by:ozo
ID: 2221349
There's HTTP_REFERER (which is part of CGI, not part of Perl)
But users can send whatever they want for that too.
0
 
LVL 1

Expert Comment

by:kesonline
ID: 2221353
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.
0
 
LVL 85

Expert Comment

by:ozo
ID: 2221374
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.
0
 
LVL 85

Expert Comment

by:ozo
ID: 2221404
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.
0
 

Author Comment

by:ardasheks
ID: 2222152
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).
0
 
LVL 85

Expert Comment

by:ozo
ID: 2222495
#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.
0
 
LVL 2

Expert Comment

by:djsansui
ID: 2223627
#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;
}
0
 
LVL 85

Expert Comment

by:ozo
ID: 2223805
#An easier way could be
@countries{
"place1" .. "place3",
} = ();

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

Featured Post

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Email validation in proper way is  very important validation required in any web pages. This code is self explainable except that Regular Expression which I used for pattern matching. I originally published as a thread on my website : http://www…
In the distant past (last year) I hacked together a little toy that would allow a couple of Manager types to query, preview, and extract data from a number of MongoDB instances, to their tool of choice: Excel (http://dilbert.com/strips/comic/2007-08…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Six Sigma Control Plans
Suggested Courses

601 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question