Print service provided by iDogiCat: http://www.idogicat.com/
home logo





Home > IT > Programming > CGI Web Programming Notes

CGI Web Programming Notes

iDog

HTTP

Print HTML Doc

Using shell:


# HTTP header
echo "Content-type: text/html; charset=iso-8859-1"
echo
echo

cat << END_OF_HTML

<ht ml>
<he ad>
    <ti tle>my title</ti tle>
</he ad>
<bo dy>

<h1>My Title</h1>

My article.

</bo dy>
</ht ml>
END_OF_HTML

Using CGI.pm:


use CGI;
use CGI::Carp qw(fatalsToBrowser);

sub getParamValue() {
    my ($q, $varName, $defaultValue) = @_;

    my $value = $q->param($varName);

    if(defined $value) {
        return $value;
    }

    if($defaultValue) {
        return $defaultValue;
    }

    return '';
}

my $q = new CGI;

my $varValue = &getParamValue($q, 'varName', 'my default value'); # from form or URL

my $title = "My Title";
print $q->header;
print $q->start_html($title);
print $q->h1($title);

print << "END_OF_HTML";

My article goes here...

END_OF_HTML

print $q->end_html;

SQL

When generating SQL using user's input, it's very important to escape single quote. Otherwise, it's easy to get affected by SQL injection attack.



sub trim {
    ($_) = @_;

    if(! defined $_) {
        return '';
    }

    s/^\s+//;
    s/\s+$//;
    $_;
}

sub processSqlStr() {
    my ($str) = @_;

    $str = &trim($str);
    if($str eq '') {
        return 'null';
    }

    $str =~ s/'/''/g;

    return "'$str'";
}

my $sql = 'update Users set name = ' . &processSqlStr($name) . " where id=0";

Thus if user's input ($name) is "Tim O'Reilly", it still works well.

Explanation of SQL injection

For example, if the login validation code is as follows:


my $sql = "select count(*) from Users where login = '$login' and pwd = '$pwd'";

# query database, if return value > 0, then validation passes

A cracker can input "' or pwd <> '" as the password to pass the validation.

URL

Special chars in URL should be escaped with their ASCII code.


my $url = "/cgi-bin/query.cgi?";
$url .= "name=$name&";
$url .= "phone=$phone";

# escape special chars
$url =~ s/\+/%2B/g;
$url =~ s/\s/+/g;

Thus a url like


/cgi-bin/query.cgi?name=Bruce Lee&phone=+1-1111-2222
becomes

/cgi-bin/query.cgi?name=Bruce+Lee&phone=%2B1-1111-2222

Or do it in a better way:


$url =~ s/([^0-9A-Za-z_ \/\?\=&])/'%'.unpack('H2',$1)/geo;
$url =~ s/\s/+/g;

Or encode/decode variables seperately:


#encode var
my $var = $q->param('varName');
$var =~ s/(\W)/'%'.unpack("H2", $1)/ego;

my $url = "http://www.example.com/my.cgi?varName=$var";

In my.cgi who accepts the variable:


my $var = $q->param('varName');
$var =~ s/%([0-9a-fA-F][0-9a-fA-F])/chr(hex($1))/ego;

# ...
print "the variable is $var";

Redirection


my $q = new CGI;
print $q->redirect($url);

By default, $q->redirect do a 302 jump. If 301 is desired, specify it explicitly:


print $q->redirect(-url => $url, -status => '301 Moved');

'-target' (target window) can also be specified.

More Options in HTML Head


use CGI;
my $q = CGI->new;
print $q->header(-charset => 'euc-jp');
print $q->start_html(
  -title    => "My title",
  -charset  => 'euc-jp',
  -encoding => 'euc-jp',
  -lang     => 'ja-JP'
);