Hello Most Holy Ones
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
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |