Quick Idea About CGI Security

October 22, 2009 by Noah

Here's a random idea that just popped into my head: to help with the security of CGI scripts, certain HTML elements in the forms can be "tagged" in various ways depending on what their function will be once submitted.

So a textarea for leaving a comment can be tagged with name="ta-comment" (ta means textarea), and an input box meant for entering user names only could be tagged with name="user-login", and an input box meant for entering numeric zip codes can be tagged name="num-zipcode".

Then, the CGI script, when it first begins parsing the query string and form parameters, can automatically apply global filters to the inputs based on their tag. This way, every input that might potentially be used to access the filesystem can be filtered so that it doesn't contain any special characters that could introduce a vulnerability in the script, but fields that are meant to be more verbatim (i.e. comment boxes) can be left largely untouched.

# Create a CGI object
my $q = new CGI();

# This will hold your script's parameters
my $args = {};

# Get all the params.
foreach my $what ($q->param) {
    my $is = $q->param($what);

    # Filter the value based on the tag.
    if ($what =~ /^num\-/) {
        # Numbers only!
        $is =~ s/[^0-9]//g;
    elsif ($what =~ /^user\-/) {
        # Usernames are numbers and letters only!
        $is =~ s/[^A-Za-z0-9]//g;
    elsif ($what =~ /^ta\-/) {
        # Textareas turn their line breaks into <br>
        $is =~ s/\n/<br>/g;
        $is =~ s/\x0d//g;
    $args->{$what} = $is;

So this way, as you write your front-end HTML code and the back-end Perl, you can tag all the inputs based on how the back-end code will plan on using them once submitted, and the code that collects the parameters when the form is submitted will be sure to format them in a consistent way. So, if your web application consistently doesn't allow quotation marks or HTML code in their text boxes, you can make the CGI automatically remove these things from all your incoming fields, and then just specially tag the ones that you want to be treated differently.

It would protect against accidental oversights by the programmer, and the end user can't do anything about it either. If the text box's name is "num-zipcode", the CGI script will always remove non-numbers when submitted and the user can't do anything about it. If they try to rename it with Firebug to be "text-zipcode" or anything like that, your CGI script won't use their version because it's not named as "num-zipcode."

I think I'll try implementing something like this next time I create a new web application.



There are 0 comments on this page. Add yours.

Add a Comment

Used for your Gravatar and optional thread subscription. Privacy policy.
You may format your message using GitHub Flavored Markdown syntax.