Spam protection for WordPress Contact Form 7 plugin

Apr 9, 2026

In WordPress contact forms, mainly using Contact Form 7 plugin, everyone notices spam messages, SEO spam or bots flooding into email inbox.

There are options to use Google reCAPTCHA or Cloudflare Turnstile but custom PHP validation is another valid way to protect against spam.

There are several filters available in Contact Form 7 to validate form fields before submission of the form.

Put this piece of code in the functions.php file of the active theme.

add_filter('wpcf7_validate_textarea', 'cf7_custom_spam_filter', 10, 2);
add_filter('wpcf7_validate_textarea*', 'cf7_custom_spam_filter', 10, 2);
add_filter('wpcf7_validate_text', 'cf7_custom_spam_filter', 10, 2);
add_filter('wpcf7_validate_text*', 'cf7_custom_spam_filter', 10, 2);

function cf7_custom_spam_filter($result, $tag) {

    $value = isset($_POST[$tag->name]) ? trim($_POST[$tag->name]) : '';
    $value_lower = strtolower($value);

    // Skip empty (let CF7 handle required validation)
    if ($value === '') return $result;

    // 1. Block URLs / links
    if (preg_match('/(http|https|www\.|\.com|\.net|\.org|\.ru|\.cn)/i', $value)) {
        $result->invalidate($tag, "Links are not allowed.");
        return $result;
    }

    // 2. Spam keywords
    $spam_keywords = [
        'viagra','cialis','casino','loan','credit','seo','crypto',
        'bitcoin','forex','trading','investment','betting','porn',
        'adult','escort','sex','free money','earn money','work from home'
    ];

    foreach ($spam_keywords as $keyword) {
        if (strpos($value_lower, $keyword) !== false) {
            $result->invalidate($tag, "Spam content detected.");
            return $result;
        }
    }

    // 3. Gibberish symbols
    if (preg_match('/[^a-zA-Z0-9\s]{6,}/', $value)) {
        $result->invalidate($tag, "Invalid input detected.");
        return $result;
    }

    // 4. Repeated characters
    if (preg_match('/(.)\1{5,}/', $value)) {
        $result->invalidate($tag, "Invalid repeating characters.");
        return $result;
    }

    // 5. Length checks
    if (strlen($value) < 3) {
        $result->invalidate($tag, "Too short.");
        return $result;
    }

    if (strlen($value) > 500) {
        $result->invalidate($tag, "Input too long.");
        return $result;
    }

    // 6. Email inside text
    if (preg_match('/[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}/i', $value)) {
        $result->invalidate($tag, "Email not allowed here.");
        return $result;
    }

    // 7. HTML tags
    if (preg_match('/<[^>]+>/', $value)) {
        $result->invalidate($tag, "HTML not allowed.");
        return $result;
    }

    return $result;
}

This code validate the form fields by blocking

Important

Make sure your message field is required otherwise some validation may be skipped.

[textarea* your-message]

Additionally, there is an option to add a simple math quiz inside the form which can further reduce spam by adding a simple human check.

[quiz math-quiz "5+3=?|8" "10-4=?|6"]