Skip to content

Commit a2a3ffe

Browse files
cport1claude
andcommitted
chore: consolidation & cleanup — detector, honeypot, dead cron, allowlist (#15)
- Single detector path: early_check now runs through the WebDecoy_Detector wrapper (SDK BotDetector + WP signals) — the same one WooCommerce uses — instead of the raw SDK detector. Score-neutral (the SDK ignores the extra WP signals; request_path was already added). - Removed the dead WebDecoy_Forms class: it was loaded but never instantiated (fully unwired), and its daily-rotation idea already lives in the honeytoken feature. The live inline honeypot remains the single honeypot implementation. - Removed the dead webdecoy_sync_blocked_ips cron (scheduled but never had a handler); existing installs get it cleared on upgrade and (de)activation. - IP allowlist: is_allowlisted() existed but nothing wrote ip_allowlist and nothing called it. Added a Blocking-tab field (IPs/CIDRs, validated on save) and wired the check into early_check so allowlisted IPs bypass all detection. - (SDK User-Agent staleness was already fixed under #1.) Verified: allowlist exact + CIDR matching, no dangling WebDecoy_Forms references, full suite green (41). Closes #15. Part of #16. Co-authored-by: Claude <noreply@anthropic.com>
1 parent ba5674e commit a2a3ffe

5 files changed

Lines changed: 34 additions & 591 deletions

File tree

‎admin/partials/settings-page.php‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,17 @@
463463
<h2><?php esc_html_e('Blocking Settings', 'webdecoy'); ?></h2>
464464

465465
<table class="form-table">
466+
<tr>
467+
<th scope="row">
468+
<label for="webdecoy_ip_allowlist"><?php esc_html_e('IP Allowlist', 'webdecoy'); ?></label>
469+
</th>
470+
<td>
471+
<textarea id="webdecoy_ip_allowlist" name="webdecoy_options[ip_allowlist]"
472+
rows="3" class="large-text code"
473+
placeholder="203.0.113.10&#10;198.51.100.0/24"><?php echo esc_textarea(is_array($options['ip_allowlist'] ?? '') ? implode("\n", $options['ip_allowlist']) : ($options['ip_allowlist'] ?? '')); ?></textarea>
474+
<p class="description"><?php esc_html_e('IPs or CIDR ranges that bypass all detection and blocking (e.g. your office, an uptime monitor). One per line. Invalid entries are discarded on save.', 'webdecoy'); ?></p>
475+
</td>
476+
</tr>
466477
<tr>
467478
<th scope="row">
468479
<label for="webdecoy_block_action"><?php esc_html_e('Block Action', 'webdecoy'); ?></label>

‎changelog.txt‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
*** WebDecoy Bot Detection Changelog ***
22

33
= 2.2.0 - Unreleased =
4+
* Added: IP allowlist — IPs or CIDR ranges that bypass all detection and blocking (Settings → Blocking). Previously the check existed internally but had no way to configure it.
5+
* Changed: Consolidated onto a single detector path (SDK detector + WordPress-signal wrapper) across front-end, forms, and WooCommerce; removed the unused legacy forms class and a dead scheduled task. No behavior change to detection.
46
* Added: Filter rules — write expression-based rules (e.g. `ip.tor or ip.abuse_score > 50`, `ip.country in ["CN","RU"] and req.path matches "^/wp-login"`) evaluated before scoring; block or throttle, with dry-run. New Settings → Rules tab with a rule builder and parse-on-save validation. Expression language is byte-for-byte compatible with @webdecoy/node.
57
* Added: IP enrichment — VPN/proxy/Tor, geo, ASN, and abuse-score data (WebDecoy Cloud) powering the ip.* filter-rule fields, cached 1 hour, fetched only when a rule needs it, fail-open.
68
* Improved: Rate limiting now runs as a rule in the engine — over-limit requests get a proper 429 with Retry-After and X-RateLimit-* headers (previously it only nudged the bot score). Adds a sliding-window algorithm (exact via a persistent object cache, falling back to the fixed-window database counter), per-IP / per-IP+route / per-user keying, and dry-run.

‎includes/class-webdecoy-activator.php‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -207,17 +207,16 @@ private static function schedule_cleanup(): void
207207
wp_schedule_event(time(), 'hourly', 'webdecoy_cleanup_expired');
208208
}
209209

210-
// Schedule blocked IP sync (every 15 minutes)
211-
if (!wp_next_scheduled('webdecoy_sync_blocked_ips')) {
212-
wp_schedule_event(time(), 'fifteen_minutes', 'webdecoy_sync_blocked_ips');
213-
}
214-
215210
// Safety-net drain of the violation-report spool (every 15 minutes).
216211
// The primary delivery path is the per-request shutdown flush; this
217212
// catches anything left behind after an ingest outage.
218213
if (!wp_next_scheduled('webdecoy_flush_violations')) {
219214
wp_schedule_event(time(), 'fifteen_minutes', 'webdecoy_flush_violations');
220215
}
216+
217+
// Note: webdecoy_sync_blocked_ips is intentionally NOT scheduled — it
218+
// never had a handler. Any leftover schedule from an older install is
219+
// cleared in activate()/deactivate().
221220
}
222221

223222
/**
@@ -230,6 +229,8 @@ public static function maybe_upgrade(): void
230229
if (version_compare($current_version, self::DB_VERSION, '<')) {
231230
self::create_tables();
232231
update_option('webdecoy_db_version', self::DB_VERSION);
232+
// Clear the dead sync-blocked-ips schedule left by older installs.
233+
wp_clear_scheduled_hook('webdecoy_sync_blocked_ips');
233234
}
234235
}
235236

0 commit comments

Comments
 (0)