Contact Us NowENDE
A Secure Contact Form with HTML, PHP, AJAX, and CSRF Protection

A Secure Contact Form with HTML, PHP, AJAX, and CSRF Protection

A contact form is an essential component of any website. In this article, we show how to create a secure contact form using HTML, PHP, and AJAX, protected with a CSRF token to prevent security vulnerabilities.

Get in Touch
Get in Touch

We are available for you.

Request a Consultation Now
By
  • Web Development
  • Inspiration
HTML Form
<form id="contact-form">
    <input type="hidden" id="csrf_token" name="csrf_token" value="">
    <label for="name">Name:</label>
    <input type="text" id="name" name="name" required>
    
    <label for="email">Email:</label>
    <input type="email" id="email" name="email" required>
    
    <label for="message">Message:</label>
    <textarea id="message" name="message" required></textarea>
    
    <button type="submit">Submit</button>
</form>
<p id="response"></p>

We create a simple HTML form.

CSRF Token

Generate and store a CSRF token in the session

<?php
session_start();
if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
echo json_encode(["csrf_token" => $_SESSION['csrf_token']]);

We add this code to a PHP file (csrf_token.php) to generate a CSRF token.

document.addEventListener("DOMContentLoaded", function () {
    fetch("csrf_token.php")
        .then(response => response.json())
        .then(data => {
            document.getElementById("csrf_token").value = data.csrf_token;
        });
});

Then, we load the token when the page loads using JavaScript.

AJAX Code

AJAX code for submitting the form

document.getElementById("contact-form").addEventListener("submit", function (e) {
    e.preventDefault();

    let formData = new FormData(this);

    fetch("process_form.php", {
        method: "POST",
        body: formData
    })
    .then(response => response.json())
    .then(data => {
        document.getElementById("response").textContent = data.message;
    })
    .catch(error => console.error("Error:", error));
});

Now, we add a script that sends the form via AJAX to process_form.php.

PHP

PHP backend with CSRF protection and email sending

<?php
session_start();
header("Content-Type: application/json");

if ($_SERVER["REQUEST_METHOD"] !== "POST") {
    echo json_encode(["message" => "Invalid request"]);
    exit;
}

if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
    echo json_encode(["message" => "CSRF validation failed"]);
    exit;
}

$name = filter_var($_POST['name'], FILTER_SANITIZE_STRING);
$email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
$message = filter_var($_POST['message'], FILTER_SANITIZE_STRING);

if (empty($name) || empty($email) || empty($message)) {
    echo json_encode(["message" => "Please fill in all fields"]);
    exit;
}

$to = "john.doe@example.com";
$subject = "New message from $name";
$headers = "From: $email\r\nReply-To: $email\r\nContent-Type: text/plain; charset=UTF-8";

$mailSent = mail($to, $subject, $message, $headers);

if ($mailSent) {
    echo json_encode(["message" => "Message sent successfully!"]);
} else {
    echo json_encode(["message" => "Error sending the message"]);
}

Here is the code for process_form.php to process the form and send the message.

Get in Touch
Get in Touch

We are available for you.

Request a Consultation Now

reCAPTCHA

Google reCAPTCHA is one of the best methods to block spam bots.

We need an API key from Google reCAPTCHA

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

<form id="contact-form">
    <input type="hidden" id="csrf_token" name="csrf_token" value="">
    <label for="name">Name:</label>
    <input type="text" id="name" name="name" required>
    
    <label for="email">Email:</label>
    <input type="email" id="email" name="email" required>
    
    <label for="message">Message:</label>
    <textarea id="message" name="message" required></textarea>
    
    <div class="g-recaptcha" data-sitekey="YOUR_SITE_KEY"></div>
    
    <button type="submit">Submit</button>
</form>

We add the reCAPTCHA script to the HTML form.

$recaptchaSecret = "YOUR_SECRET_KEY";
$recaptchaResponse = $_POST['g-recaptcha-response'];

$verifyResponse = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret={$recaptchaSecret}&response={$recaptchaResponse}");
$responseData = json_decode($verifyResponse);

if (!$responseData->success) {
    echo json_encode(["message" => "Please verify reCAPTCHA"]);
    exit;
}

We verify the reCAPTCHA token in process_form.php.

Honeypot

Add a hidden input field that only bots fill out, but is invisible to real users.

<input type="text" name="honeypot" style="display:none;">

We add a hidden input field to the HTML form.

if (!empty($_POST['honeypot'])) {
    echo json_encode(["message" => "Spam detected!"]);
    exit;
}

We check the honeypot in process_form.php.

Time-Based Validation

Store a timestamp in the session when the form loads and check if the form was filled out in a realistic amount of time.

session_start();
$_SESSION['form_time'] = time();

We initiate time-based validation in csrf_token.php.

if (time() - $_SESSION['form_time'] < 5) {
    echo json_encode(["message" => "Form filled out too quickly, suspicious request!"]);
    exit;
}

We verify time-based validation in process_form.php.

Conclusion: A Secure and Modern Contact Form

With this setup, you have a secure and modern contact form that uses AJAX to avoid page reloads and includes CSRF protection to prevent attacks. This ensures your contact form operates reliably and securely.

Can we assist you?
Can we assist you?

Can we assist you?

Get in Touch

Why is a CSRF token important?

A CSRF token prevents Cross-Site Request Forgery (CSRF) attacks by ensuring that only authorized requests are accepted.

Can I use the form without JavaScript?

Yes, but without JavaScript, the page will reload upon submission. The form can also be processed with a traditional PHP POST request.

Why isn’t my email being sent?

Check if your server supports the mail() function. Alternatively, you can use PHPMailer.

How can I further customize the form?

Add additional fields, enhance styling with CSS, or integrate with a database.

Is the form protected against spam?

This example does not include spam protection. The article explains how to add spam protection.

Can I have multiple forms on one page?

Yes, but each form needs its own CSRF token, or you must make the token available for all forms.

How can we help you?
How can we help you?

Our services cover all areas of digital communication.

Write to Us
weedesign Blog

Responsive Web Design - How to Do It Right

Responsive web design is an approach where websites are developed to be optimally displayed on various devices and screen sizes. A well-implemented responsive website automatically adjusts to the size of the respective screen, thus providing an optimal user experience on desktop computers, laptops, tablets, and smartphones.

To the Blog Post

A Secure Contact Form with HTML, PHP, AJAX, and CSRF Protection

A contact form is an essential component of any website. In this article, we show how to create a secure contact form using HTML, PHP, and AJAX, protected with a CSRF token to prevent security vulnerabilities.

To the Blog Post

Shopware vs Shopify: A Comparison of Modern E-Commerce Platforms

Shopware and Shopify are among the leading e-commerce platforms for companies that want to make their online business efficient and modern. While Shopware is primarily widespread in the DACH region, Shopify convinces with global reach and user-friendliness. In this comparison, we analyze both systems regarding features, usability, costs, and performance.

To the Blog Post
Looking for Shopware Extensions?
Here are our bestsellers!
Advanced Editor | WYSIWYG

Advanced Editor | WYSIWYG

Use the advanced WYSIWYG editor in Shopware 6. This editor enables easy embedding of media in descriptions and many additional features.

ab 7.99 €* / Month

Optimize PageSpeed

Optimize PageSpeed

Optimize your shop to create a better experience for your customers. This plugin minimizes your shop’s loading time and offers numerous configuration options.

ab 27.49 €* / Month

Twig Manager
Twig Manager

Quickly and easily create and edit your own template extensions in the administration. Displays existing storefront template paths and contents.

ab 3.99 €* / Month

Note: * All prices are exclusive of VAT

x