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
| Setting | Default | Meaning |
|---|---|---|
| Max retries | 10 | Failed attempts before lockout |
| Window | 5 minutes | Rolling window for the counter |
| Lockout duration | 5 minutes | How 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.
| Setting | Character |
|---|---|
3 | Aggressive — locks out fast. Good during active attack |
10 | Balanced default |
25 | Lenient — only catches obvious abusers |
0 | Effectively disables rate-limit |
Lockout Time (minutes)
- Option key:
wkcft_lockout_time - Tab: Conditional Rules → Abuse Protection
- Default:
5minutes
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:
HTTP_CF_CONNECTING_IPheader (set by Cloudflare)HTTP_X_FORWARDED_FOR(first IP, if multiple)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:
| Scenario | Behavior |
|---|---|
| IP on whitelist | Skips CAPTCHA entirely — never increments counter |
| IP on blacklist | Always requires CAPTCHA — every fail increments |
| Normal IP | Standard 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/hourfor 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
| Filter | Default | Purpose |
|---|---|---|
wkcft_rate_limit_threshold | 10 | Max failures before lockout |
wkcft_rate_limit_window | 300 (sec) | Rolling window for the counter |
wkcft_fail_counter_window | 1800 (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
