Skip to main content

Spam Protection

Core Forms provides five layers of spam protection that can be used individually or combined. Spam submissions are stored in the database (marked as spam) but do not trigger any actions.

Protection Methods

1. Honeypot Field (Default On)

A hidden field that legitimate users never see or fill in. Bots that auto-fill all fields will be caught. This is enabled by default on all forms with no configuration required.

The honeypot field is rendered inside the form automatically and hidden with CSS. If it contains a value on submission, the submission is flagged as spam.

2. Google reCAPTCHA v3

Invisible score-based CAPTCHA that runs in the background without user interaction.

Setup:

  1. Go to Core Forms > Settings > Spam Protection
  2. Enter your reCAPTCHA v3 Site Key and Secret Key
  3. Save settings

reCAPTCHA is automatically added to all forms when configured. It evaluates user behavior and assigns a score (0.0 to 1.0). Scores below the threshold are flagged as spam.

// The reCAPTCHA integration hooks into form validation
add_filter( 'cf_validate_form', [ $recaptcha, 'validate_recaptcha' ], 10, 3 );

// And adds the reCAPTCHA widget to form markup
add_filter( 'cf_form_markup', [ $recaptcha, 'add_recaptcha_to_form' ], 10, 2 );

// And enqueues the script when a form is rendered
add_filter( 'cf_form_html', [ $recaptcha, 'enqueue_recaptcha_on_form_render' ], 10, 2 );

3. Cloudflare Turnstile

A privacy-focused CAPTCHA alternative from Cloudflare. Presents a simple widget that verifies users without puzzles.

Setup:

  1. Go to Core Forms > Settings > Spam Protection
  2. Enter your Turnstile Site Key and Secret Key
  3. Save settings
add_filter( 'cf_validate_form', [ $turnstile, 'validate_turnstile' ], 10, 3 );
add_filter( 'cf_form_markup', [ $turnstile, 'add_turnstile_to_form' ], 10, 2 );
add_filter( 'cf_form_html', [ $turnstile, 'enqueue_turnstile_on_form_render' ], 10, 2 );

4. Akismet Integration

Leverages the Akismet anti-spam service (requires the Akismet plugin to be installed and configured).

Akismet checks submission content against its global spam database. It runs at a lower priority (20) so it executes after CAPTCHA checks:

add_filter( 'cf_validate_form', [ $akismet, 'check_for_spam' ], 20, 3 );

5. Math CAPTCHA

A simple math question (e.g., "What is 3 + 7?") that bots typically cannot solve. No external service required.

add_filter( 'cf_validate_form', [ $math, 'validate_math_captcha' ], 15, 3 );
add_filter( 'cf_form_markup', [ $math, 'add_math_captcha_to_form' ], 20, 2 );

Validation Order

Spam checks run in priority order via the cf_validate_form filter:

Priority Check Class
10 reCAPTCHA v3 Recaptcha
10 Cloudflare Turnstile Turnstile
15 Math CAPTCHA MathCaptcha
20 Akismet Akismet

The honeypot is checked separately during form processing in Forms::process().

Spam Handling

When a submission is flagged as spam:

  1. The is_spam flag is set to true on the submission.
  2. The submission is saved to the database (so you can review false positives).
  3. No actions are triggered -- no emails, webhooks, or integrations fire.
  4. A success response is returned to the browser to trick bots into thinking the submission succeeded.
  5. A spam analytics event is recorded for reporting.

Custom Validation

Add your own spam checks using the cf_validate_form filter:

add_filter( 'cf_validate_form', function( $error_code, $form, $data ) {
    // If another validator already flagged an error, pass through
    if ( '' !== $error_code ) {
        return $error_code;
    }

    // Block submissions with known spam phrases
    $spam_phrases = [ 'buy now', 'click here', 'free offer' ];
    $message = strtolower( $data['message'] ?? '' );

    foreach ( $spam_phrases as $phrase ) {
        if ( strpos( $message, $phrase ) !== false ) {
            return 'spam';
        }
    }

    return $error_code;
}, 25, 3 );

Recommended Configuration

Form Type Recommended Protection
Contact form (low traffic) Honeypot + Math CAPTCHA
Contact form (high traffic) Honeypot + Turnstile or reCAPTCHA
Public-facing form Honeypot + Turnstile + Akismet
Internal/logged-in form Honeypot only

Related