HDP
HDP

Reputation: 4221

Still receiving spam even Google reCaptcha v3 enabled in PhpMailer Contact Form

We are using below code for my PhpMailer Contact Form. and, It is working fine normally. but, I'm still receiving spam even though I have recaptcha v3 enabled.

Screenshot of spam email:

enter image description here

Said this one of my friend:

bots send POST requests to /php/mail.php and the email get sent even if they the request doesn’t come from my domain and didn’t pass reCAPTCHA.

Can you please any help. Is there a mistake in the code below?

HTML Form Code:

<form id="contact-form" class="form-border" action="php/mail.php" method="post">
              <div class="form-group mb-4">
                <label for="name">What is Your Name:</label>
                <input id="name" name="name" type="text" class="form-control py-1" required >
              </div>
              <div class="form-group mb-4">
                <label for="email">Your Email Address:</label>
                <input id="email" name="email" type="email" class="form-control py-1" required >
              </div>
              <div class="form-group mb-4">
                <label for="form-message">How can I Help you?:</label>
                <textarea id="form-message" name="form-message" class="form-control py-1" rows="4" required ></textarea>
              </div>
              <p>
                <button id="submit-btn" class="btn btn-dark rounded-0 d-inline-flex" type="submit">Send <span class="ml-3"><i class="fas fa-arrow-right"></i></span></button>
              </p>
            </form>

Bottom of the HTML page:

<script id="google-recaptcha-v3" src="https://www.google.com/recaptcha/api.js?render=xxxxxxxxxxxxxxxxxxxxxx"></script>

JS Code:

var form = $('#contact-form'); // contact form
var submit = $('#submit-btn'); // submit button

// form submit event
form.on('submit', function (e) {
    e.preventDefault(); // prevent default form submit

    if (typeof $('#google-recaptcha-v3').val() != "undefined") {
        grecaptcha.ready(function () {
            var site_key = $('#google-recaptcha-v3').attr('src').split("render=")[1];
            grecaptcha.execute(site_key, {action: 'contact'}).then(function (token) {
                var gdata = form.serialize() + '&g-recaptcha-response=' + token;
                $.ajax({
                    url: 'php/mail.php',  // form action url
                    type: 'POST',         // form submit method get/post
                    dataType: 'json',     // request type html/json/xml
                    data: gdata,          // serialize form data
                    beforeSend: function () {
                        submit.attr("disabled", "disabled");
                        var loadingText = '<span role="status" aria-hidden="true" class="spinner-border spinner-border-sm align-self-center mr-2"></span>Sending.....'; // change submit button text
                        if (submit.html() !== loadingText) {
                            submit.data('original-text', submit.html());
                            submit.html(loadingText);
                        }
                    },
                    success: function (data) {
                        submit.before(data.Message).fadeIn("slow"); // fade in response data 
                        submit.html(submit.data('original-text'));// reset submit button text
                        submit.removeAttr("disabled", "disabled");
                        if (data.response == 'success') {
                            form.trigger('reset'); // reset form
                        }
                        setTimeout(function () {
                            $('.alert-dismissible').fadeOut('slow', function(){
                                $(this).remove();
                            });
                        }, 3000);
                    },
                    error: function (e) {
                        console.log(e)
                    }
                });
            });
        });
    } else {
        $.ajax({
            url: 'php/mail.php', // form action url
            type: 'POST', // form submit method get/post
            dataType: 'json', // request type html/json/xml
            data: form.serialize(), // serialize form data
            beforeSend: function () {
                submit.attr("disabled", "disabled");
                var loadingText = '<span role="status" aria-hidden="true" class="spinner-border spinner-border-sm align-self-center mr-2"></span>Sending.....'; // change submit button text
                if (submit.html() !== loadingText) {
                    submit.data('original-text', submit.html());
                    submit.html(loadingText);
                }
            },
            success: function (data) {
                submit.before(data.Message).fadeIn("slow"); // fade in response data 
                submit.html(submit.data('original-text'));// reset submit button text
                submit.removeAttr("disabled", "disabled");
                if (data.response == 'success') {
                    form.trigger('reset'); // reset form
                }
                setTimeout(function () {
                    $('.alert-dismissible').fadeOut('slow', function(){
                        $(this).remove();
                    });
                }, 3000);
                if (typeof $('#recaptcha-v2').val() != "undefined") {
                    grecaptcha.reset(); // reset reCaptcha
                }
            },
            error: function (e) {
                console.log(e)
            }
        });
    }
});

PHP Code: (mail.php)

<?php

/*--------------------------------------------------

    Name:           Contact Form

----------------------------------------------------*/

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

require './phpmailer/src/Exception.php';
require './phpmailer/src/PHPMailer.php';
require './phpmailer/src/SMTP.php';


/* --------------------------------------------
  // Receiver's Email
--------------------------------------------- */

$toEmail = "[email protected]"; // Replace Your Email Address


/* --------------------------------------------
  // Sender's Email
--------------------------------------------- */

$fromEmail = "[email protected]";  // Replace Company's Email Address (preferably currently used Domain Name)
$fromName = "Company Name"; // Replace Company Name


/* --------------------------------------------
  // reCaptcha Secret
  --------------------------------------------- */

// Add this only if you want to use Google reCaptcha with your Contact Forms.
$recaptcha_secret = 'YOUR_RECAPTCHA_SECRET_KEY'; // Your Google reCaptcha Secret


/* --------------------------------------------
  // Subject
--------------------------------------------- */
$subject = "Your Website Form Response"; // Your Subject


if (isset($_POST['name'])) {

/*-------------------------------------------------
    PHPMailer Initialization
---------------------------------------------------*/

$mail = new PHPMailer(true);

/* Add your SMTP Codes after this Line */


// End of SMTP

if (filter_var($toEmail, FILTER_VALIDATE_EMAIL)) {

    $mail->AddAddress($toEmail);
    $mail->setFrom($fromEmail, $fromName);
    $mail->addReplyTo($_POST['email'], $_POST['name']);

    $mail->isHTML(true);
    $mail->CharSet = 'UTF-8';
    
    $mail->Subject = $subject . ' [' . $_POST['name'] . ']';

    $mail->Body = '<table align="center" border="0" cellpadding="0" cellspacing="20" height="100%" width="100%">
                        <tr>
                            <td align="center" valign="top">
                                <table width="600" bgcolor="#f8f6fe" cellpadding="7" style="font-size:16px; padding:30px; line-height: 28px;">
                                    <tr>
                                        <td style="text-align:right; padding-right: 20px;" width="100" valign="top"><strong>Name:</strong></td>
                                        <td>' . $_POST['name'] . '</td>
                                    </tr>
                                    <tr>
                                        <td style="text-align:right; padding-right: 20px;" width="100" valign="top"><strong>Email:</strong></td>
                                        <td>' . $_POST['email'] . '</td>
                                    </tr>
                                    <tr>
                                        <td style="text-align:right; padding-right: 20px;" width="100" valign="top"><strong>Message:</strong></td>
                                        <td>' . $_POST['form-message'] . '</td>
                                    </tr>
                                </table>
                            </td>
                        </tr>
                    </table>';
    
    /*-------------------------------------------------
        reCaptcha
    ---------------------------------------------------*/
    $message = array(
        'recaptcha_invalid' => 'Captcha not Validated! Please Try Again!',
        'recaptcha_error' => 'Captcha not Submitted! Please Try Again.'
    );
    $message_form = !empty($_POST['message']) ? $_POST['message'] : array();
    $message['recaptcha_invalid'] = !empty($message_form['recaptcha_invalid']) ? $message_form['recaptcha_invalid'] : $message['recaptcha_invalid'];
    $message['recaptcha_error'] = !empty($message_form['recaptcha_error']) ? $message_form['recaptcha_error'] : $message['recaptcha_error'];

    if (isset($_POST['g-recaptcha-response'])) {
        $recaptcha_data = array(
            'secret' => $recaptcha_secret,
            'response' => $_POST['g-recaptcha-response']
        );

        $recap_verify = curl_init();
        curl_setopt($recap_verify, CURLOPT_URL, "https://www.google.com/recaptcha/api/siteverify");
        curl_setopt($recap_verify, CURLOPT_POST, true);
        curl_setopt($recap_verify, CURLOPT_POSTFIELDS, http_build_query($recaptcha_data));
        curl_setopt($recap_verify, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($recap_verify, CURLOPT_RETURNTRANSFER, true);
        $recap_response = curl_exec($recap_verify);
        $g_response = json_decode($recap_response);

        if ($g_response->success !== true) {
            echo json_encode(array('response' => 'error', 'Message' => '<div class="alert alert-danger alert-dismissible fade show text-3 text-left"><i class="fa fa-times-circle"></i> ' . $message['recaptcha_invalid'] . '<button type="button" class="close font-weight-500 mt-1" data-dismiss="alert">&times;</button></div>'));
            exit;
        }
    }

    $forcerecap = (!empty($_POST['force_recaptcha']) && $_POST['force_recaptcha'] != 'false' ) ? true : false;
    if (isset($g_response->action) && $g_response->action == 'contact') {
        if (isset($g_response->success) && $g_response->success == true && $g_response->action == 'contact') {
            
        } else if ($forcerecap) {
            if (!isset($_POST['g-recaptcha-response'])) {
                echo json_encode(array('response' => 'error', 'Message' => '<div class="alert alert-danger alert-dismissible fade show text-3 text-left"><i class="fa fa-times-circle"></i> ' . $message['recaptcha_error'] . '<button type="button" class="close font-weight-500 mt-1" data-dismiss="alert">&times;</button></div>'));
                exit;
            }
        } else {
            echo json_encode(array('response' => 'error', 'Message' => '<div class="alert alert-danger alert-dismissible fade show text-3 text-left"><i class="fa fa-times-circle"></i> ' . $message['recaptcha_error'] . '<button type="button" class="close font-weight-500 mt-1" data-dismiss="alert">&times;</button></div>'));
            exit;
        }
    }
    //----- reCaptcha End -----//

    $success = "Thank you for contacting us and will be in touch with you very soon."; // Success Message

    try {
        $resp = $mail->send();
        echo json_encode(array('response' => 'success', 'Message' => '<div class="alert alert-success alert-dismissible fade show text-3 text-left"><i class="fa fa-check-circle"></i> ' . $success . ' <button type="button" class="close font-weight-500 mt-1" data-dismiss="alert">&times;</button></div>'));
        exit;
    } catch (Exception $e) {
        echo json_encode(array('response' => 'error', 'Message' => '<div class="alert alert-danger alert-dismissible fade show text-3 text-left"><i class="fa fa-times-circle"></i> Message could not be sent: ' . $e->errorMessage() . '<button type="button" class="close font-weight-500 mt-1" data-dismiss="alert">&times;</button></div>'));
        exit;
    } catch (\Exception $e) {
        echo json_encode(array('response' => 'error', 'Message' => '<div class="alert alert-danger alert-dismissible fade show text-3 text-left"><i class="fa fa-times-circle"></i> Message could not be sent: ' . $e->getMessage() . '<button type="button" class="close font-weight-500 mt-1" data-dismiss="alert">&times;</button></div>'));
        exit;
    }
} else {
    echo json_encode(array('response' => 'error', 'Message' => '<div class="alert alert-danger alert-dismissible fade show text-3 text-left"><i class="fa fa-times-circle"></i> There is a invalid <strong>Receivers Email</strong> address! <button type="button" class="close font-weight-500 mt-1" data-dismiss="alert">&times;</button></div>'));
    exit;
}
} else {
    echo json_encode(array('response' => 'error', 'Message' => '<div class="alert alert-danger alert-dismissible fade show text-3 text-left"><i class="fa fa-times-circle"></i> There is a problem with the document! <button type="button" class="close font-weight-500 mt-1" data-dismiss="alert">&times;</button></div>'));
    exit;
}
?>

Upvotes: 0

Views: 4127

Answers (1)

Surjith S M
Surjith S M

Reputation: 6740

It seems you are using ReCaptcha v3, but not validating the ReCaptcha score. in v3, if it's spam, ReCaptcha still returns success with a score eg: 0.1 or 0.2, if human, it should be above 0.5. So you should use that to validate instead.

Here's an example code:

$recaptcha_url      = 'https://www.google.com/recaptcha/api/siteverify';
$recaptcha_secret   = $secret;
$recaptcha_response = $_POST['recaptcha_response'];

// Make and decode POST request:
$recaptcha_response        = url_get_contents( $recaptcha_url . '?secret=' . $recaptcha_secret . '&response=' . $recaptcha_response );
$google_recaptcha_response = json_decode( $recaptcha_response );

if (!$google_recaptcha_response->success || empty($google_recaptcha_response->success)) { 
    echo "reCAPTCHA verification failed.";
  // echo $google_recaptcha_response;

} else {
    if ($google_recaptcha_response->score >= 0.5) {
        // Verified
        // Process form  here 

Upvotes: 2

Related Questions