Turnstile CAPTCHA For WooCommerceTurnstile CAPTCHA For WooCommerce
Buy Now
View Demo
  • Getting Started

    • Introduction
    • Quick Start
    • Features
    • Installation
    • First-Time Setup
    • Get Turnstile Keys
    • Onboarding Wizard
  • Settings

    • Settings Overview
    • API Settings
    • General
    • Design Studio
    • Conditional Rules
    • Per-Form Config
    • Notifications
  • Supported Forms

    • All Supported Forms
    • WooCommerce Forms
    • WordPress Forms
    • Third-Party Form Plugins
    • Checkout Blocks
    • Shortcode
  • Protection & Monitoring

    • Analytics Dashboard
    • Rate Limiting
    • Recovery URL
    • Email Digest
    • Webhooks
  • Developer

    • REST API
    • Filters & Hooks
    • Site Health
  • Compare

    • vs reCAPTCHA
    • vs hCaptcha
  • Help

    • Troubleshooting
    • FAQ
    • Glossary
Support
Buy Now
View Demo
  • Getting Started

    • Introduction
    • Quick Start
    • Features
    • Installation
    • First-Time Setup
    • Get Turnstile Keys
    • Onboarding Wizard
  • Settings

    • Settings Overview
    • API Settings
    • General
    • Design Studio
    • Conditional Rules
    • Per-Form Config
    • Notifications
  • Supported Forms

    • All Supported Forms
    • WooCommerce Forms
    • WordPress Forms
    • Third-Party Form Plugins
    • Checkout Blocks
    • Shortcode
  • Protection & Monitoring

    • Analytics Dashboard
    • Rate Limiting
    • Recovery URL
    • Email Digest
    • Webhooks
  • Developer

    • REST API
    • Filters & Hooks
    • Site Health
  • Compare

    • vs reCAPTCHA
    • vs hCaptcha
  • Help

    • Troubleshooting
    • FAQ
    • Glossary
Support
  • Getting Started

    • Introduction
    • Quick Start — Turnstile Live in 5 Minutes
    • Features — Everything the Plugin Can Do
    • Installation — Full Setup Guide
    • First-Time Setup
    • Get Turnstile Keys from Cloudflare
    • Onboarding Wizard
  • Settings

    • Settings Overview — All 9 Tabs
    • API Settings Tab
    • General Settings Tab
    • Design Studio Tab
    • Conditional Rules Tab
    • Per-Form Config Tab
    • Notifications Tab
  • Supported Forms

    • All Supported Forms
    • WooCommerce Forms
    • WordPress Forms
    • Third-Party Form Plugins
    • Checkout Blocks Integration
    • Shortcode — Drop the Widget Anywhere
  • Protection & Monitoring

    • Analytics Dashboard
    • Rate Limiting — Auto-Lockout for Abusive IPs
    • Recovery URL — Unlock a Stuck IP
    • Email Digest
    • Webhooks — Real-Time Alerts on Bot Spikes
  • Developer

    • REST API
    • Filters & Hooks
    • Site Health Integration
  • Compare

    • Turnstile vs Google reCAPTCHA
    • Turnstile vs hCaptcha
  • Help

    • Troubleshooting
    • Frequently Asked Questions
    • Glossary

Rate Limiting — Auto-Lockout for Abusive IPs

After N failed CAPTCHA attempts in a rolling window, the offending IP is locked out. Further submissions from that IP are rejected immediately without even hitting Cloudflare — saving server and Cloudflare API calls.

Default Thresholds

SettingDefaultMeaning
Max retries10Failed attempts before lockout
Window5 minutesRolling window for the counter
Lockout duration5 minutesHow long the IP stays locked

After the lockout window passes, the counter resets.

Tunable From the UI

Max Retries

  • Option key: wkcft_max_retries
  • Tab: Conditional Rules → Abuse Protection

Lower values = tighter protection. Higher values = more lenient.

SettingCharacter
3Aggressive — locks out fast. Good during active attack
10Balanced default
25Lenient — only catches obvious abusers
0Effectively disables rate-limit

Lockout Time (minutes)

  • Option key: wkcft_lockout_time
  • Tab: Conditional Rules → Abuse Protection
  • Default: 5 minutes

How long the IP stays blocked after hitting the threshold.

Use longer lockouts for high-value endpoints (checkout). Use shorter for high-traffic endpoints (comments) to avoid accidental blocks on shared IPs.

Filter Hooks

For code-level tuning:

// Change threshold
add_filter('wkcft_rate_limit_threshold', function() {
    return 20; // 20 failures instead of 10
});

// Change rolling window (seconds)
add_filter('wkcft_rate_limit_window', function() {
    return 600; // 10-minute window
});

// Change after-N-failures counter window (seconds)
add_filter('wkcft_fail_counter_window', function() {
    return 1800; // 30 minutes
});

How It Works Under the Hood

Transient-Based Buckets

  • Every failed validation increments a transient: wkcft_rl_md5(IP)
  • Transient TTL = lockout window
  • When counter > threshold, all future requests from that IP are rejected

Proxy-Aware IP Detection

The plugin gets the real visitor IP even when behind Cloudflare:

  1. HTTP_CF_CONNECTING_IP header (set by Cloudflare)
  2. HTTP_X_FORWARDED_FOR (first IP, if multiple)
  3. REMOTE_ADDR (direct connection)

Code in WKCFT_Plugin::wkcft_get_real_ip().

Replay Protection (Separate From Rate Limiting)

The plugin also blocks token replay:

  • Every successful token is recorded in a transient wkcft_used_md5(TOKEN) for 5 minutes
  • If the same token is submitted twice, the second submission fails with prohibited-replay

This is different from rate-limit lockout — replay is per-token, rate-limit is per-IP.

Logging

Every rate-limit lockout is recorded in the wp_wkcft_log table with error_code = 'rate-limited'.

See those events on Analytics Dashboard → Error Breakdown → rate-limited slice.

Interaction with Conditional Rules

Rate-limiting runs AFTER the Conditional Rules:

ScenarioBehavior
IP on whitelistSkips CAPTCHA entirely — never increments counter
IP on blacklistAlways requires CAPTCHA — every fail increments
Normal IPStandard flow — fails increment counter

IPs on the whitelist can NEVER be rate-limited. The counter is never incremented for them.

Blocked Usernames List

Complementary feature — usernames that always fail login regardless of password.

  • Option key: wkcft_blocked_usernames
  • Tab: Conditional Rules → Abuse Protection
  • Format: Comma or newline separated

Pre-populate with common targets:

admin
administrator
root
wordpress
user
test
guest
demo

Bots scanning for default admin credentials hit a wall without burning CAPTCHA attempts. Your real admin username should be something unique and NOT on this list.

Clearing a Locked IP

Method 1 — Recovery URL

Use the Recovery URL — one-time-use secret that clears a specific IP's lockout.

https://yoursite.com/?wkcft_recovery=YOUR_TOKEN

Method 2 — Admin Database Cleanup

If a specific IP got stuck and you have database access:

DELETE FROM wp_options 
WHERE option_name LIKE '_transient_wkcft_rl_%' 
   OR option_name LIKE '_transient_timeout_wkcft_rl_%';

This clears ALL rate-limit transients (not just one IP).

Method 3 — Wait It Out

Lockout auto-expires after wkcft_lockout_time minutes. Default 5 minutes.

Bypass for Your Own IP

Add your office/home IP to the IP whitelist. Whitelisted IPs never accumulate failures.

Tuning Advice

Low-Traffic Site, Occasional Bot Hits

  • Max retries: 10 (default)
  • Lockout time: 5 (default)
  • Window: 5 min (default)

Under Active Attack

  • Max retries: 3
  • Lockout time: 30 min
  • Add top IPs from analytics to blacklist
  • Set webhook threshold to 10/hour for real-time alerts

High-Traffic Store With False Positives

  • Max retries: 20
  • Window: 10 min
  • Whitelist any of your team's office / VPN IPs

Filter Reference

FilterDefaultPurpose
wkcft_rate_limit_threshold10Max failures before lockout
wkcft_rate_limit_window300 (sec)Rolling window for the counter
wkcft_fail_counter_window1800 (sec)Window for require_after_failures counter

Related Pages

  • Conditional Rules — Where to set max retries + lockout time
  • Recovery URL — Clear a stuck IP
  • Analytics — See rate-limited events
  • Filters & Hooks — Full filter reference
Prev
Analytics Dashboard
Next
Recovery URL — Unlock a Stuck IP