0
votes

I've made a contact form for a website that works - so well that bots spam the company using it. Not good.

I've looked into adding a google recaptcha validation system.

I've succesfully added the widget to the website as well as gone so far as:

  • Website returns an error to the user if captcha isn't verified when they click submit.
  • Website shows correct affirmation message when captcha is verified and they press submit.

So far so good.

The issue:

The form sends regardless of the captcha. So regardless if it actually shows the error to the user about the captcha being verified or not, it still submits the message - ultimately making this bot stopping recaptcha worthless. It looks nice... but is it really? Not yet.

I suspect it's the .js validation script I have that does this. I've tried a few things like changing order of code around etc, but my newbie status really makes it hard and I'm close to giving up.

My form uses php, ajax for instant verification if form is sent, js and the good old html and css.

.PHP:

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'vendor/autoload.php';

$firstname = ($_POST['firstname']);
$lastname = ($_POST['lastname']);
$phone = ($_POST['phone']);
$email = ($_POST['email']);
$message = ($_POST['message']);
$msg = ($_POST['msg']);
$okMessage = ' SUCCESS ';
$errorMessage = ' ERROR';

$secretKey = " EXAMPLE ";
$responseKey = $_POST['g-recaptcha-response'];
$userIP = $_SERVER['REMOTE_ADDR'];

$mail = new PHPMailer(true);
try {
    $mail->SMTPDebug = 0;
    $mail->isSMTP();
    $mail->Host       = ' EXAMPLE ';
    $mail->SMTPAuth   = true;
    $mail->Username   = ' EXAMPLE ';
    $mail->Password   = ' EXAMPLE ';
    $mail->SMTPSecure = 'ssl';
    $mail->Port       = 465;
    $mail->WordWrap = 50;
    $mail->Priority = 1;
    $mail->CharSet = 'utf-8';

    $mail->setFrom(' EXAMPLE ', ' EXAMPLE ');
    $mail->addAddress(' EXAMPLE ');
    $mail->addReplyTo($email);
    $mail->isHTML(true);

    $url = "https://www.google.com/recaptcha/api/siteverify?secret=$secretKey&response=$responseKey&remoteip=$userIP";
    $response = file_get_contents($url);
    $response = json_decode($response);

    $mail->Subject = 'NY BESKED -  EXAMPLE';
    $mail->Body    = (' EXAMPLE ');
    $mail->AltBody = (' EXAMPLE ');

    if (!$mail->send() || !$response->success) {
        throw new \Exception('ERROR TRY AGAIN' . $mail->ErrorInfo);
    } else  {
        $responseArray = array('type' => 'success', 'message' => $okMessage);
    }

} catch (\Exception $e) {
    $responseArray = array('type' => 'danger', 'message' => $e->getMessage());
}

if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
    $encoded = json_encode($responseArray);
    header('Content-Type: application/json');
    echo $encoded;
} else {
    echo $responseArray['message'];
}

JS PART:

$(function ValidateEmailForm() {
    window.verifyRecaptchaCallback = function (response) {
        $('input[data-recaptcha]').val(response).trigger('change')
    };
    window.expiredRecaptchaCallback = function () {
        $('input[data-recaptcha]').val("").trigger('change')
    };
    $('#contact-form').validator();
    $('#contact-form').on('submit', function (e) {
        if (!e.isDefaultPrevented()) {
            var url = "contact.php";

            $.ajax({
                type: "POST",
                url: url,
                data: $(this).serialize(),
                success: function (data) {
                    var messageAlert = 'alert-' + data.type;
                    var messageText = data.message;

                    var alertBox = '<div class="alert ' + messageAlert + ' alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>' + messageText + '</div>';
                    if (messageAlert && messageText) {
                        $('#contact-form').find('.messages').html(alertBox);
                        $('#contact-form')[0].reset();
                        grecaptcha.reset();
                    }
                }
            });
            return false;
        }
    });
});

and the HTML part:

          <script src="https://www.google.com/recaptcha/api.js" async defer></script>

          <div class="col-12 d-flex justify-content-center">
            <div class="g-recaptcha" data-sitekey="6Lf80bUUAAAAADrnadBM_GYs0PY8p4QqP7ol45ac"></div>
          </div>

What's the issue here? Thank you in advance!

1

1 Answers

1
votes

Your conditions are backwards. You should check the captcha first:

if (!$response->success || !$mail->send()) {