Hello Most Holy Ones

Update:

I opened up a can of worms with this one, but they'd been in there so long it was time to let them out. Since I asked this question, I have implemented all new forms on our website, and *none* of them use any version of FormMail.pl. Thank you to everyone for your input!

(end of update)

I have been trying to figure out how to put a honeypot in a cgi script that validates a complex form. The cgi script is based on that old, security-flawed chestnut Formmail.pl.

What I've done is inserted a bogus field in the form, hidden by css, and I want to filter for that field in the cgi--see if it's empty, and if it's not print a message and exit the program. This is what I came up with, and it's breaking a script that otherwise works:

elsif (($name{'bogusfield'}) && ($name{'bogusfield'}) ne ' ') { print <h3>"Thank you. Your request has been submitted."</h3>; exit (); }

I'm not sure whether it is the code I've written that is wrong, or where I'm putting it. I am inserting it in the sub to parse the form, which seems logical to me, but maybe I need a separate subroutine for this?

Here is the code to parse the form, with the honeypot code in it:

sub parse_form { if ($ENV{'REQUEST_METHOD'} eq 'GET') { # Split the name-value pairs @pairs = split(/&/, $ENV{'QUERY_STRING'}); } elsif ($ENV{'REQUEST_METHOD'} eq 'POST') { # Get the input read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); # Split the name-value pairs @pairs = split(/&/, $buffer); } else { &error('request_method'); } foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $name =~ tr/+/ /; $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; # If they try to include server side includes, erase them, so th +ey # aren't a security risk if the html gets returned. Another # security hole plugged up. $value =~ s/<!--(.|\n)*-->//g; # Create two associative arrays here. One is a configuration ar +ray # which includes all fields that this form recognizes. The othe +r # is for fields which the form does not recognize and will repor +t # back to the user in the html return page and the e-mail messag +e. # Also determine required fields. if ($name eq 'recipient' || $name eq 'subject' || $name eq 'email' || $name eq 'realname' || $name eq 'redirect' || $name eq 'bgcolor' || $name eq 'background' || $name eq 'link_color' || $name eq 'vlink_color' || $name eq 'text_color' || $name eq 'alink_color' || $name eq 'title' || $name eq 'sort' || $name eq 'print_config' || $name eq 'return_link_title' || $name eq 'return_link_url' && ($value)) { $CONFIG{$name} = $value; } elsif (($name{'bogusfield}) && ($name{'bogusfield'}) ne ' ') { print <h3>"Thank you. Your request has been submitted."</h3>; exit (); } elsif ($name eq 'required') { @required = split(/,/,$value); } elsif ($name eq 'env_report') { @env_report = split(/,/,$value); } else { if ($FORM{$name} && ($value)) { $FORM{$name} = "$FORM{$name}, $value"; } elsif ($value) { $FORM{$name} = $value; } } } }

Does anyone know what is wrong? :-)

Many thanks!


In reply to CGI Honeypot? by Hans Castorp

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.