I have a question about Perl from the script below. If the input for the $user variable is joeshmo; ls -l;, perl will only print out joeshmo if the line print $user is coded. My intuition tells me that all of joeshmo; ls -l; should be printed. However, if the user variable is given to finger to be executed, both joeshmo and ls -l are executed. I ask this because I am trying to limit the input that is allowed to the variable $user with a statement like
if (($user !~ /^[a-z_A-Z0-9]+[-+%]*[a-z_A-Z0-9]+$/)){
die "The entered user name uses characters not of the alphanumeric form or the \"-\", \"+\", or \"%\"!";
}
else{
In the above statement I believe that the only input that will not cause the program to die are statements with alphanumeric characters and an underscore followed by -, +, % characters (if any are desired) and then another round of alphanumeric characters and an underscore. However, regular expression only evaluates the first part of the $user variable and not the entire thing as is the case with the in put joeshmo; ls -l;. The regular expression is only evaluated on joeshmo.
Another interesting piece of information that I do not understand is why the semicolons do not show up when the $user variable is printed? If they were, I could just search for those, but they are not printed and thus they are not able to be evaluated on a regular expression.
I would appreciate any help on these matters!
#!/usr/bin/perl
use CGI;
use CGI::Carp qw(fatalsToBrowser);
$q = new CGI;
print $q->header,
$q->start_html('Finger User'),
$q->h1('Finger User');
print "<pre>\n";
$user = $q->param("user");
print "\n";
print $user;
print "\n\n";
if (($user !~ /^[a-z_A-Z0-9]+[-+%]*[a-z_A-Z0-9]+$/)){
die "The entered user name uses characters not of the alphanumeric form or the \"-\", \"+\", or \"%\"!";
}
else{
print `/usr/bin/finger -s $user`;
}
print "</pre>";
print $q->end_html;
I don’t think you’re
ls -lis getting into$userat all. If it was, then your regex, which would be better written as$user !~ /^\w+[-+%]*\w+$/, would match and yourdiewould be executed. I’m guessing that you’re calling this script asSome implementations allow a semicolon (
;) to be used as a separator in query strings so that above would be (with some server implementations) equivalent to:and so, the
ls -lpart would not be considered part ofuser. Try URL encoding the semicolons and the spaces:and then you should see your
ls -land trigger thedie.The reason that
;is sometimes allowed as a separator is that&is also used by HTML for encoding entities, so, any ampersands that appear in an HTML attribute should be encoded as&or you’re risking confusion; for example, this will often misbehave:but this won’t:
In the HTML4 spec, the W3 recommends: