3
\$\begingroup\$

I managed to make a very simple contact form.

I used PHP for server-side validation and reCAPTCHA v2.

You can access the form at the following link: https://test.dexsolutions.digital/index.php

And this is the code:

index.php

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Contact Form</title>
  <link rel="stylesheet" href="css/style.css">
  <link rel="stylesheet" href="css/normalize.css">
  <script src="https://www.google.com/recaptcha/api.js" async defer></script>
</head>
<body>

  <div class="container">
    <?php include 'contact.php';?>
    <h2>Contact Us</h2>
    <form action="index.php" method="post">
      <p>
        <label for="inputName">Name:</label>
        <input type="text" name="name" id="inputName" value="<?php echo $name; ?>" placeholder="Write your name here..">
        <span class="error"><?php echo $nameErr; ?></span>
      </p>
      <p>
        <label for="inputEmail">Email:</label>
        <input type="email" name="email" id="inputEmail" value="<?php echo $email; ?>" placeholder="Let us know how to contact you back..">
        <span class="error"><?php echo $emailErr; ?></span>
      </p>
      <p>
        <label for="inputComment">Message:</label>
        <textarea name="message" id="inputComment" rows="5" cols="30" placeholder="What would you like to tell us.."><?php echo $message; ?></textarea>
        <span class="error"><?php echo $messageErr; ?></span>
      </p>
      <div class="group">
        <div class="g-recaptcha" data-sitekey="my-sitekey"></div>
        <span class="error"><?php echo $robot; ?></span>
        <input class="btn" type="submit" value="Send">
      </div>
    </form>
  </div>

</body>
</html>

contact.php

<?php

// Functions to filter user inputs
function filterName($field){
    // Sanitize user name
    $field = filter_var(trim($field), FILTER_SANITIZE_STRING);

    // Validate user name
    if(filter_var($field, FILTER_VALIDATE_REGEXP, array("options"=>array("regexp"=>"/^[a-zA-Z\s]+$/")))){
        return $field;
    } else{
        return FALSE;
    }
}    
function filterEmail($field){
    // Sanitize e-mail address
    $field = filter_var(trim($field), FILTER_SANITIZE_EMAIL);

    // Validate e-mail address
    if(filter_var($field, FILTER_VALIDATE_EMAIL)){
        return $field;
    } else{
        return FALSE;
    }
}
function filterString($field){
    // Sanitize string
    $field = filter_var(trim($field), FILTER_SANITIZE_STRING);
    if(!empty($field)){
        return $field;
    } else{
        return FALSE;
    }
}

// Define variables and initialize with empty values
$nameErr = $emailErr = $messageErr = "";
$name = $email = $message = $robot = "";

// Processing form data when form is submitted
if($_SERVER["REQUEST_METHOD"] == "POST"){

    // Validate user name
    if(empty($_POST["name"])){
        $nameErr = "Please enter your name.";
    } else{
        $name = filterName($_POST["name"]);
        if($name == FALSE){
            $nameErr = "Please enter a valid name.";
        }
    }

    // Validate email address
    if(empty($_POST["email"])){
        $emailErr = "Please enter your email address.";     
    } else{
        $email = filterEmail($_POST["email"]);
        if($email == FALSE){
            $emailErr = "Please enter a valid email address.";
        }
    }

    // Validate user message
    if(empty($_POST["message"])){
        $messageErr = "Please enter your message.";     
    } else{
        $message = filterString($_POST["message"]);
        if($message == FALSE){
            $messageErr = "Please enter a valid message.";
        }
    }

    if(isset($_POST['g-recaptcha-response'])){
        $secret = 'my_secret_code';
        $verifyResponse = file_get_contents('https://www.google.com/recaptcha/api/siteverify?    secret='.$secret.'&response='.$_POST['g-recaptcha-response']);
        $responseData = json_decode($verifyResponse);
    }

    if($responseData->success === false) {
        $robot = "Robot verification failed!";
    }

    // Check input errors before sending email
    if(empty($nameErr) && empty($emailErr) && empty($messageErr) && ($responseData->success === true)){

        // Recipient email address
        $to = '[email protected]';
    
        // Create email headers
        $headers = 'From: '. $email . "\r\n" .
        'Reply-To: '. $email . "\r\n" .
        'X-Mailer: PHP/' . phpversion();
    
        // Sending email
        if(mail($to, $message, $headers)){
            echo '<p class="success">Your message has been sent successfully!</p>';
            $name = $email = $message = "";
            /* header("Location: success.html"); */
        } else{
            echo '<p class="error">Unable to send email. Please try again!</p>';
        }
    }
}
?>

I wonder if this form is safe? It also seems to me that I messed around a bit when I want to show that reCAPTCHA v2 is not ok.

Any suggestions and criticisms are welcome.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for the review, interesting article, what is a good replacement for google reCAPTCHA, and that it is easy to implement, because I am a beginner? \$\endgroup\$
    – user230470
    Apr 15, 2021 at 13:54

1 Answer 1

1
\$\begingroup\$

I think that your code looks fine, but have you really thought about the usage of Google's reCAPTCHA?

When you include Google's reCAPTCHA in your site you're giving Google access to your site and to your visitors. If that's what you want, fine, but perhaps you shouldn't be doing this? For instance, when when you have a medical advice site, it is not the best idea to let your visitors be tracked by Google. It has to do with privacy. If I slightly exaggerate I could call this form: "not safe", purely because Google's behind it.

You can also read this: https://onezero.medium.com/google-promises-recaptcha-isn-t-exploiting-users-should-you-trust-it-ed99f1543f28

Google's reCAPTCHA does a very good job at filtering out bots, or other unwanted form submissions. I don't think you could get anything better, simply because Google has such vast resources, and probably already knows everything about the visitor, it can do this job very well. The question is whether you really need the best solution, given its obvious disadvantages.

There are other methods. For instance you could use a well chosen "honey pot". Many other methods exist like a simple tick box, submitting using AJAX, time-analysis, etc.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.