Usa reCAPTCHA con FormMail

Importante: Ya no se admite la versión 1.0 de la API de reCAPTCHA. Actualiza a la versión 2.0. Más información

Aquí, te explicaremos cómo agregar reCAPTCHA a tu secuencia de comandos FormMail sin usar el módulo de Perl de reCAPTCHA. Si sabes lo que estás haciendo, también puedes usar el módulo de Perl de reCAPTCHA.

Del cliente (cómo hacer que aparezca la imagen CAPTCHA)

En tu página HTML, dentro del elemento <form>, debes agregar el siguiente código:

  <script type="text/javascript"
    src="http://www.google.com/recaptcha/api/challenge?k=your_public_key">
  </script>
  <noscript>
    <iframe src="http://www.google.com/recaptcha/api/noscript?k=your_public_key"
        height="300" width="500" frameborder="0"></iframe>

    <textarea name="recaptcha_challenge_field" rows="3" cols="40">
    </textarea>
    <input type="hidden" name="recaptcha_response_field"
        value="manual_challenge">
  </noscript>

Probablemente no hace falta decirlo, pero lo diremos de todos modos: debes reemplazar las dos instancias de your_public_key por la clave pública que recibiste durante el proceso de creación de la cuenta. Ten cuidado de no usar tu clave privada por error.

Básicamente, esto agregará dos parámetros, que se pasan a formmail.cgi (o FormMail.pl) a través de una solicitud POST, a saber:

  • recaptcha_challenge_field: Este es el desafío creado a través de tu clave pública.
  • recaptcha_response_field: Es la respuesta que envió el usuario al desafío anterior.
  • En el servidor (cómo comprobar si el usuario ingresó la respuesta correcta)

    A continuación, debes modificar formmail.cgi (o FormMail.pl) para controlar los dos parámetros y validar el desafío desde los servidores de reCAPTCHA. En este punto, probablemente sea una buena idea hacer una copia de seguridad de FormMail.pl, por si acaso. En el siguiente código, "+" significa que la línea debe agregarse a la secuencia de comandos FormMail, y "-" significa que se debe quitar la línea. En cada caso, mostramos dónde se deben agregar o quitar las líneas mostrando las líneas adyacentes en la secuencia de comandos FormMail.

    Primero, debes indicarle a Perl que use el módulo LWP::UserAgent. Para ello, agrega la siguiente línea a FormMail:

     # ACCESS CONTROL FIX: Peter D. Thompson Yezek                                #
     #                     http://www.securityfocus.com/archive/1/62033           #
     ##############################################################################
     +use LWP::UserAgent;
     +
    

    (esto requerirá que el módulo LWP::UserAgent esté en el entorno de Perl. La mayoría de las instalaciones de Perl ya tienen este módulo. En caso de que el módulo no esté instalado, aquí encontrarás algunas instrucciones básicas para instalar módulos de Perl).

    Luego, agrega el código para invocar la funcionalidad de verificación de CAPTCHA que se define a continuación.

     # 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;
    

    Ahora, valida la respuesta de CAPTCHA y genera un error si no coincide con el desafío.

     +##############################################################################
     +# Check the CAPTCHA response via the reCAPTCHA service.
     +sub check_captcha {
     +
     +      my $ua = LWP::UserAgent->new();
     +      my $result=$ua->post(
     +      'https://www.google.com/recaptcha/api/verify',
     +      {
     +          privatekey => 'your_private_key',
     +          remoteip   => $ENV{'REMOTE_ADDR'},
     +          challenge  => $Form{'recaptcha_challenge_field'},
     +          response   => $Form{'recaptcha_response_field'}
     +      });
     +
     +      if ( $result->is_success && $result->content =~ /^true/) {
     +              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.                                                   #
    

    Por último, crea la funcionalidad que imprime el mensaje de error en caso de que falle la verificación:

             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><font size=+2>Error: Captcha Check Failed</font></th></tr%gt;
     +   </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%gt;
     +    </td></tr>
     +   </table>
     +  </center>
     + </body>
     +</html>
     +(END ERROR HTML)
     +    }
             else {
                  foreach $missing_field (@error_fields) {
                      $missing_field_list .= "<li>" . &clean_html($missing_field) . "\n";
     .
     .
     .
      </html>
     (END ERROR HTML)
             }
     -    }
     -
         exit;
     }
    

    Eso es todo. reCAPTCHA ya debería estar funcionando en tu sitio.

    Material de lectura adicional

  • Cómo personalizar la apariencia
  • Sugerencias y lineamientos
  • Solución de problemas