Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I am inviting a larger audience to try out a simple spell check cgi on my web server. I'm pretty sure I am not leaving security holes. Am I missing something obvious? Thanks much. -Michael
#!/usr/local/bin/perl use CGI qw/:standard unescape/; # This code segment is designed to accept parameters via HTTP to CGI # and spell check each word. The resulting output is displayed with # non-match words highlighted. my $open_html_indicator = '<b><font color="#FF0000">'; my $close_html_indicator = '</b></font>'; my $i; my %hash; my %misspelled_words; my $varname; my $mydata; my %dict; # Parse the parameters from the calling HTTP line my @values = split(/&/,$ENV{'QUERY_STRING'}); foreach $i (@values) { ($varname, $mydata) = split(/=/,$i); $hash{$varname} = unescape($mydata); #unescape clears out http %20 etc. } # Response header to send back to the requesting web page print header; print << 'EOL'; <html><head><title>Spell Check API Example</title></head> <body> <font face="Arial" size=2> EOL # Load the dictionary word list into a hash open DICT,"</usr/dict/words2"; # This just points to a word list while(<DICT>){ chomp; $dict{lc($_)}=1; } close DICT; print "<H3> The following $open_html_indicator highlighted $close_html +_indicator words" . " are not found in the English dictionary </H3> <br>"; print "<table border='1'>"; while ( ($varname, $mydata) = each %hash ) { my @words=split /[^a-zA-Z0-9']+/,$mydata; foreach (@words){ if(!defined $dict{lc($_)}){ if(!defined $misspelled_word{$_}){ # If the data is already caught , then move on $misspelled_word{$_} = 1; $mydata =~ s/$_/$open_html_indicator $_ $close_html_ +indicator/g; } } } print "<tr><td><br><b>$varname:</b> $mydata<br></td></tr>"; } print "</table>"; print "<br><br><font size='1'> Spell Check API Example </font>"; print "</body>"; print "</html>";

Replies are listed 'Best First'.
Re: Is this secure?
by diotalevi (Canon) on Nov 14, 2003 at 19:49 UTC

    You neglected CGI.pm's parameter code - that's a big problem. Outside of that while your code is pretty ugly it'll work. Here's your code re-written.

    use CGI qw/:all/; use vars qw($DICT_FILE %DICT $CSS); $CSS = ".highlight { font-weight: bold; color: #F00; } * { font-size: medium; font-family: sans-serif; }"; $DICT_FILE = "/usr/dict/words2"; open DICT, "<", $DICT_FILE or die "Couldn't open $DICT_FILE: $!"; while ( my $word = <DICT> ) { chomp $word; $DICT{lc $word} = undef; } close DICT or warn "Couldn't close $DICT_FILE: $!"; # Response header to send back to the requesting web page print header(), start_html( -title => 'Spell Check API Example', -style => $CSS, ), h3("The following " . span( { class => 'highlight' }, 'highlighted' ) . " words are not found in the English dictionary."), br(), start_table( { border => 1 } ); for my $param ( sort param() ) { my @words = split ' ', param($param); for my $word ( @words ) { if ( not exists $DICT{lc $word} and not exists $KNOWN_MISPELLINGS{lc $word} ) { $word = span( { class => 'highlight' }, $word ); } } print Tr( td( b( $param ), ' ', join(' ', @words) ) ); } print end_table(), br(), br(), span( { -font_size => small }, 'Spell Check API Example' ), end_html();
Re: Is this secure?
by jpfarmer (Pilgrim) on Nov 14, 2003 at 19:27 UTC

    You made a good choice using the CGI module, and that well help a lot, but I'm concerned that you're not using the Taint, Strict, or Warnings pragmas. If you're worried about security in your code, you should be using those as a first step. Also, consider using the CGI module to parse the incoming parameters for you. That is one of the most valuable aspects of CGI, and it will increase the security of your program.

    Other than that, nothing major jumps out at me. However, I'd want to make sure it runs under the pragmas I listed above before I let it go live.

Re: Is this secure?
by Anonymous Monk on Nov 14, 2003 at 19:30 UTC
    THanks all. For some reason I had never heard of Taint. I'll look into it. As to Params - I use them now. This block was my second program in Perl. I'll update it to use the proper param model. Thanks again. -Michael
A reply falls below the community's threshold of quality. You may see it by logging in.