The use of parameters in itself doesn't open the opportunity for hackers to attack your server. It's what your code DOES with the parameters.
For instance, if you use param variables to read or write to files, or put them into an eval statement, or anything similar like that, it can lead to problems if somebody puts in data that you weren't expecting.
For example, a calculator CGI with a source like this:
Code:
use CGI;
my $q = new CGI;
my $expr = $q->param ('expr');
my $result = eval($expr); # if $expr = "2 + 10 / 2" $result = 7
print "Content-Type: text/html\n\n";
if ($expr) {
print "$expr = $result<p>";
}
print "<form action='calc.cgi'><input type=text name=expr><input type=submit>";
Well, in that case, if somebody typed something into the text box which wasn't a mathematical calculation (i.e. they could type
unlink ("*.*"), then the script would run that command and you'd be in some big trouble.
With reading files, say you have a site management system where a parameter "page" opens a text file to insert content into the page:
Code:
use CGI;
my $q = CGI->new;
my $page = $q->param ("page");
open (PAGE, "./private/pages/$page\.txt");
my @page = <PAGE>;
close (PAGE);
chomp @page;
print "Content-Type: text/html\n\n";
print join ("\n",@page);
Well, in that case, they could run a URL like this:
Code:
index.cgi?page=../users/admin
And instead of reading ./private/pages/admin.txt, it would read ./private/
users/admin.txt and if that's where you keep private user data, they could potentially read your password.
Or they could even go as far as to do something like
Code:
index.cgi?page=/home/some/private/folder
They could potentially read every file on your system which could pose a serious security risk.
So, parameters can be dangerous only when you're not filtering them. A common rule of thumb is to simply never trust the information coming in. A simple solution to that file reading code is to filter out any dots or slashes in the parameter text, not allowing them to change directories in it. Or for the calculator, remove everything from $expr that isn't a mathematical operator:
Code:
$page =~ s/(\.|\/|\\)//g; # remove . and \ and / from $page
$expr =~ s/[^0-9\+\-\*\/ ]//g; # remove everything from $expr except numbers, +, -, *, /, and spaces
In the example with the calculator, you don't want to allow the backslash \ -- only allow the forward slash / as this is the one used in division in programming languages. Allowing a \ allows a l33t hacker to run malicious codes too, because \ is the escape character (for example, \123 might represent a certain ASCII character, and your calculator would fully accept it. A hacker could run all the escape codes to spell out "unlink" or any other Perl command).
So, when writing code, think of all the possible things somebody could do when sending in data, never trust the data coming in, and be especially cautious when using that data to run program code or read or write files, or basically, anytime the variables "do" anything, make sure that they can't "do" everything at the same time.