How to integrate reCAPTCHA with javascript PERL and formmail.cgi

From reCAPTCHA Wiki

Jump to: navigation, search

reCAPTCHA + Javascript + formmail.cgi

recaptcha_challenge_field
This is the challenge created through your public key.
recaptcha_response_field
This is the user submitted response to the challenge above.
  • Modify the formmail.cgi to handle the two parameters and to validate the challenge from the reCaptcha servers, through the PERL API.
URL
http://search.cpan.org/dist/Captcha-reCAPTCHA/lib/Captcha/reCAPTCHA.pm

Example Code for formmail.cgi

  • To protect your private key, place it outside the web root.
--- formmail.cgi	2008-02-06 12:34:14.000000000 +0200
+++ formmail-cap.cgi	2008-07-11 09:57:06.000000000 +0300
@@ -23,9 +23,15 @@
# ACCESS CONTROL FIX: Peter D. Thompson Yezek                                #
#                     http://www.securityfocus.com/archive/1/62033           #
##############################################################################
+use Captcha::reCAPTCHA;
+use lib "/path/to/somewhere/outside/webroot/captcha";
+use Keys qw(PUBLIC_KEY PRIVATE_KEY );
+
  • Below is the PERL module code, which contains the PUBLIC_KEY and PRIVATE_KEY constants (Keys.pm needs to be placed outside the web root, which is then included into formmail.cgi).
package Keys;

@ISA=qw(Exporter);
@EXPORT= qw(PUBLIC_KEY PRIVATE_KEY);
use constant PUBLIC_KEY => "<your public key goes here>";
use constant PRIVATE_KEY => "<your private key goes here>";

1;
__END__
  • Initialize a new reCAPTCHA object:
# Define Variables                                                           #
#      Detailed Information Found In README File.                            #
 
+$captcha = Captcha::reCAPTCHA->new;
+
# $mailprog defines the location of your sendmail program on your unix       #
# system. The flags -i and -t should be passed to sendmail in order to       #
# have it ignore single dots on a line and to read message for recipients    #
@@ -76,12 +82,35 @@
  • Call the captcha check functionality defined below.
# Check Required Fields
&check_required;
 
+# Check the captcha challenge and response.
+&check_captcha;
+
# Send E-Mail
&send_mail;

# Return HTML Page or Redirect User
&return_html;

  • Validate the captcha response and generate an error, if the response doesn't match the challenge.
+##############################################################################
+# Check the captcha response via the reCaptcha service.
+sub check_captcha {
+    if ( $Form{'recaptcha_response_field'} ) {
+        $result = $captcha->check_answer(
+          PRIVATE_KEY, $ENV{'REMOTE_ADDR'},
+          $Form{'recaptcha_challenge_field'} ,
+          $Form{'recaptcha_response_field'} )
+    } else {
+        &error('captcha_failed');
+    }
+    delete $Form{'recaptcha_challenge_field'}; 
+    delete $Form{'recaptcha_response_field'};
+    if ( $result->{is_valid} ) {
+        return;
+    } else {
+        &error('captcha_failed');
+    }
+}
+
# NOTE rev1.91: This function is no longer intended to stop abuse, that      #
#    functionality is now embedded in the checks made on @recipients and the #
#    recipient form field.                                                   #
  • Create the functionality, which prints the error message, if the check fails.
@@ -744,6 +773,32 @@
        if ($Config{'missing_fields_redirect'}) {
            print "Location: " . &clean_html($Config{'missing_fields_redirect'}) . "\n\n";
        }
+    }
    elsif ($error eq 'captcha_failed') {
+            print <<"(END ERROR HTML)";
+Content-type: text/html
+
+<html>
+ <head>
+  <title>Error: Captcha Check Failed</title>
+ </head>
+ <body bgcolor=#FFFFFF text=#000000>
+ <center>
+  <table border=0 width=600 bgcolor=#9C9C9C>
+    <tr><th>Error: Captcha Check Failed</th></tr>
+   </table>
+  <table border=0 width=600 bgcolor=#CFCFCF>
+    <tr><td>The Captcha response of the form you submitted did not match the challenge.
+     Please check the form and make sure that your response matches the challenge in the captcha image.
+     You can use the browser back button to return to the form.
+     </center>
+    </td></tr>
+   </table>
+  </center>
+ </body>
+</html>
+(END ERROR HTML)
+    }
        else {
             foreach $missing_field (@error_fields) {
           $missing_field_list .= "<li>" . &clean_html($missing_field) . "\n";
@@ -779,8 +834,6 @@
 </html>
(END ERROR HTML)
        }
-    }
-
    exit;
}
Personal tools