WordPress Plugin
Detect bots and AI crawlers in your WordPress dashboard, review the evidence, then enable protection. Local detection and protection need no WebDecoy account or API key. Cloud sync is optional.
Install the free WordPress plugin → · Watch the setup walkthrough · Compare install methods
Install in about 3 minutes
Section titled “Install in about 3 minutes”- In WordPress Admin, open Plugins → Add New.
- Search for WebDecoy, then choose Install Now → Activate.
- Open WebDecoy → Settings. Keep Monitor mode on while you review the first detections.
- Send the reserved test request, then open WebDecoy → Detections to find the test entry. This works without cloud sync.
- Review normal login, form and checkout activity before enabling blocking. Connect WebDecoy Cloud later if you want central reporting.
Prefer WP-CLI? Run this from your own WordPress installation:
wp plugin install webdecoy --activateSuccess looks like: the WebDecoy admin menu appears, monitor mode is active, and your controlled test appears in the local detection log. An empty log before testing does not mean installation failed.
If the site is behind Cloudflare, a load balancer, or a managed host proxy, configure Client IP / Reverse Proxy before enabling blocking. Detection can work with the wrong client IP while enforcement would affect the wrong visitor.
Watch installation through the first detection
Section titled “Watch installation through the first detection”The walkthrough shows WebDecoy 2.10.5 on a fresh local site: install, inspect a controlled canary detection, choose an AI crawler policy, and test enforcement. The canary check in the video is distinct from the reserved test request below, which returns a test receipt without banning your IP.
Follow the illustrated setup guide for the commands, observed responses and rollout checks.
Plugin Overview
Section titled “Plugin Overview”The WebDecoy WordPress plugin provides comprehensive bot protection for WordPress sites without writing any code. All detection and protection works locally: no API key or WebDecoy account required. It combines server-side detection, client-side JavaScript scanning, behavioral scoring, an invisible proof-of-work challenge, and form protection. Connecting to WebDecoy Cloud (optional) adds dashboard sync and cross-site actor intelligence.
For supported use cases and plan information, see the WordPress and WooCommerce product page.
Features
Section titled “Features”| Feature | Description |
|---|---|
| Server-Side Detection | IP analysis, rate limiting, user-agent checking |
| Client-Side Scanner | JavaScript-based bot and automation detection |
| Form Protection | Honeypot fields for comments, login, registration |
| WooCommerce Protection | Checkout velocity limiting, card testing detection |
| Good Bot Handling | Allowlist for search engines, social bots, AI crawlers |
| Local Blocking | Block IPs directly in WordPress |
| Invisible PoW Challenge | Suspicious visitors solve a proof-of-work page before proceeding |
| Tripwires | Deterministic blocking of hidden scanner-bait paths (/.env, /.git/config) |
| Filter Rules | Expression rules (ip.tor, ip.abuse_score > 50) evaluated before scoring |
| Monitor Mode | Detect and log everything, block nothing. This is the default |
| Statistics & Export | Local statistics page with trends, CSV export of detections |
| Cloud Sync (optional) | Sync detections to the WebDecoy dashboard, one click or an API key |
How It Works
Section titled “How It Works”WordPress Request │ ▼┌─────────────────────────────┐│ WebDecoy Plugin │├─────────────────────────────┤│ 1. IP Block Check ││ 2. Rate Limit Check ││ 3. Good Bot Check ││ 4. Server-Side Analysis ││ 5. Client-Side Scanner │├─────────────────────────────┤│ Decision: Allow/Block │└─────────────────────────────┘ │ ▼Detection → Stored locally + Synced to WebDecoyInstalling the WordPress Plugin
Section titled “Installing the WordPress Plugin”The plugin requires WordPress 6.1 or later and is tested up to WordPress 7.1.
Method 1: The WordPress.org directory (Recommended)
Section titled “Method 1: The WordPress.org directory (Recommended)”- In WordPress Admin, go to Plugins → Add New
- Search for WebDecoy
- Click Install Now, then Activate
This is the build most sites should run: WordPress handles updates for you, from wordpress.org/plugins/webdecoy.
Method 2: Download from CDN (self-hosted build)
Section titled “Method 2: Download from CDN (self-hosted build)”-
Download the Plugin
- Go to
https://cdn.webdecoy.com/wordpress/ - Download the latest
webdecoy-x.x.x.zipfile
- Go to
-
Upload to WordPress
- In WordPress Admin, go to Plugins → Add New
- Click Upload Plugin
- Choose the downloaded ZIP file
- Click Install Now
-
Activate
- Click Activate Plugin
- You’ll see “WebDecoy” in the admin menu
Method 3: Manual Installation
Section titled “Method 3: Manual Installation”-
Download and Extract
Terminal window unzip webdecoy-x.x.x.zip -
Upload via FTP
- Upload the
webdecoyfolder to/wp-content/plugins/
- Upload the
-
Activate in WordPress
- Go to Plugins in WordPress Admin
- Find “WebDecoy” and click Activate
Verifying Installation
Section titled “Verifying Installation”After activation:
- “WebDecoy” menu appears in WordPress Admin
- Status shows “Plugin Active”
- Database tables are created automatically
If you have connected the site to WebDecoy Cloud, the Sensors page in the dashboard (sidebar, under Countermeasures) is the fastest way to confirm the plugin is actually reporting. Your site’s card lists a WordPress sensor with when it was last seen and its detection counts over 24h and 7d. A site with nothing installed says so plainly: “Nothing is installed on this site, so WebDecoy cannot see any traffic to it.”
Fire a test detection
Section titled “Fire a test detection”The fastest end-to-end proof (requires the latest plugin version): send one request with the reserved test User-Agent. The plugin always records it and answers with a 403 JSON receipt, so the curl output itself shows the plugin acted:
curl -A "WebDecoy-Test/1.0" https://your-site.example/The detection appears immediately on the plugin’s own Detections admin page. On a connected site it also reaches the cloud dashboard within seconds, labeled Test (excluded from stats and billing). The test never blocks your IP and never trips enforcement rules.
Plugin Configuration
Section titled “Plugin Configuration”Accessing Settings
Section titled “Accessing Settings”- Click WebDecoy in the WordPress Admin menu
- Click Settings
- Configure options across multiple tabs
Settings Tabs
Section titled “Settings Tabs”| Tab | What it controls |
|---|---|
| Protection (default) | Sensitivity, block threshold, rate limits, client IP / reverse proxy |
| Tripwires | Hidden scanner-bait paths and what a hit does |
| Rules | Expression-based filter rules, evaluated before scoring |
| Good Bots | Search engine / AI crawler / monitoring allowances |
| Blocking | Monitor mode, local IP block list, block behavior |
| Forms | Honeypot fields for comments, login, registration |
| Scanner | Client-side detection script options |
| WooCommerce | Checkout protection (shown when WooCommerce is active) |
| WebDecoy Cloud | Connect the site to the dashboard |
Behind Cloudflare or a proxy? Read this first
Section titled “Behind Cloudflare or a proxy? Read this first”This is the setting most likely to make a correct install look broken.
By default the plugin uses the direct connection IP and ignores forwarding headers like
X-Forwarded-For and CF-Connecting-IP, because those headers can be spoofed by anyone who
can reach your site. If your site is behind Cloudflare, a load balancer, or most managed
hosts, every visitor otherwise resolves to the proxy’s own address: detections all share one
IP, rate limits fire on the aggregate, and a block would hit everyone at once.
To fix it, go to Settings → Protection and find the row Client IP / Reverse Proxy:
- Tick “This site is behind Cloudflare” if you are on Cloudflare. The plugin then reads
the real visitor IP from
CF-Connecting-IP, but only when the request genuinely arrives from a Cloudflare address. - For any other proxy, put its addresses in Additional trusted proxy IPs / CIDRs, one IP or CIDR range per line (for example your load balancer). Leave it blank for a direct setup.
- Save. Forwarding headers are now trusted only when the connection actually comes from one of those.
Both can be used together. Neither is on by default.
The plugin tells you when this is wrong
Section titled “The plugin tells you when this is wrong”Since 2.3.2 it does not just get the IPs wrong quietly. When it sees a forwarding header on an admin request and no trusted proxy is configured, it stops blocking and shows a red admin notice:
WebDecoy is not blocking: this site is behind a proxy it has not been told about. Your requests arrive with
CF-Connecting-IP, but no trusted proxy is configured. Until that is fixed every visitor looks like the same address, so blocking anyone would block everyone.Detection, logging and reporting continue as normal. Only blocking, rate limiting and the 403 page are withheld.
The notice links to Configure trusted proxies. Detection keeps working throughout, so you lose enforcement, not visibility.
Monitor mode
Section titled “Monitor mode”Settings → Blocking, first row: Monitor mode, labelled “Watch only, detect and log everything, block nothing”.
It is on by default, for both new installs and sites upgraded from an earlier version. Every other setting on the page still decides what would happen and the Detections page still shows it, but no visitor is ever blocked, throttled, or shown a 403. Turn it off once you have looked at what enforcement would have done.
While it is on, the admin shows an informational notice: “WebDecoy is in monitor mode.” with either “Enforcing would have acted on N requests in the last 30 days” or “No request has met the bar for enforcement yet”, plus a Review and turn on blocking button.
Monitor mode applies at every point the plugin can act on a request, including the WooCommerce checkout, the honeytoken coupon, the challenge interstitial, login, comments and registration. Earlier versions gated only the rule engine, which is how a site could show “nothing is blocked” in the admin while still refusing traffic.
The emergency off switch
Section titled “The emergency off switch”Add this to wp-config.php to stop the plugin acting on the front end entirely, without
needing database access:
define('WEBDECOY_DISABLE', true);Nothing is detected or blocked while it is defined, and the admin says so. This exists so you can always recover over FTP.
WebDecoy Cloud Tab (optional)
Section titled “WebDecoy Cloud Tab (optional)”Everything works without this. Connecting adds dashboard sync.
One click (recommended). Press Connect to WebDecoy Cloud. It opens WebDecoy Cloud to approve the connection and returns you here automatically; the plugin exchanges a one-time token server-side and stores the provisioned keys encrypted at rest. No data leaves your site until you press it. There is a “Send me a monthly security report” opt-in on the same screen.
Once connected the tab shows Connected to WebDecoy Cloud, the state of the monthly report, and Disconnect.
By hand. Manual credentials still work, under the Advanced: manual configuration section. Most sites do not need it:
| Setting | Description |
|---|---|
| API Key | Your WebDecoy API key (sk_live_...) from the dashboard’s API Keys page |
| Site Key | Publishable key for the browser clearance client |
Click Test Connection; status shows Active, Inactive, Connection Error, or “Not checked yet”. If cloud sync is off, the plugin keeps protecting your site locally, and only the dashboard sync is affected.
Detection Settings
Section titled “Detection Settings”Configure how the plugin detects and responds to threats.
Detection Tab Settings
Section titled “Detection Tab Settings”| Setting | Default | Description |
|---|---|---|
| Enable Protection | Yes | Master on/off switch |
| Sensitivity | Medium | Detection strictness |
| Minimum Score to Block | 75 | Score threshold for blocking |
| Rate Limit Enabled | Yes | Enable request rate limiting |
| Requests Per Minute | 60 | Max requests before rate limit |
Sensitivity Levels
Section titled “Sensitivity Levels”| Level | Behavior |
|---|---|
| Low | Minimal detection, very few false positives |
| Medium | Balanced detection and accuracy (recommended) |
| High | Maximum detection, may have false positives |
Blocking Actions
Section titled “Blocking Actions”| Action | Behavior |
|---|---|
| Block | Return 403 Forbidden |
| Challenge | Serve the invisible proof-of-work page. No third-party CAPTCHA is involved |
| Log Only | Record but don’t block |
Tripwires can also Challenge or Log rather than only blocking or serving deception (2.3.4). Log is the safest way to watch a tripwire you have just armed. Note that Challenge needs JavaScript and a click, which can add friction for simple HTTP clients. Browser automation can execute JavaScript and click, so completing the challenge does not prove a visitor is human. Review the detection evidence and test legitimate visitor flows before enabling enforcement.
Block Duration
Section titled “Block Duration”On Settings → Blocking, Block Duration is in hours, and 0 means permanent.
The default is 1 hour, changed from 24 in 2.3.2: a long block on a shared or reassigned address mostly risks blocking whoever inherited it next. Upgrading rewrites the old 24-hour default, but leaves any value you chose yourself alone.
Automatic blocks are also bounded. The plugin refuses to auto-block loopback, private or reserved ranges, a configured trusted proxy, or the current request’s proxy front door, and it will not write a range wider than /24 (IPv4) or /48 (IPv6). Refusals are recorded and surfaced rather than failing silently. Blocks you type in by hand are unaffected.
Good Bot Handling
Section titled “Good Bot Handling”Configure which bots are allowed through without detection.
Good Bots Tab Settings
Section titled “Good Bots Tab Settings”| Setting | Default | Description |
|---|---|---|
| Allow Search Engines | Yes | Googlebot, Bingbot, Yahoo, etc. |
| Allow Social Media Bots | Yes | Facebook, Twitter, LinkedIn, Pinterest |
| Block AI Crawlers | No | GPTBot, ClaudeBot, etc. |
| Custom Allowlist | Empty | Your own bot user agents |
Search Engine Bots Recognized
Section titled “Search Engine Bots Recognized”- Googlebot
- Bingbot
- Yahoo! Slurp
- DuckDuckBot
- Baiduspider
- YandexBot
Social Media Bots Recognized
Section titled “Social Media Bots Recognized”- Facebook External Hit
- Twitterbot
- LinkedInBot
- Slackbot
AI Crawlers (Optional Block)
Section titled “AI Crawlers (Optional Block)”- GPTBot (OpenAI)
- ClaudeBot (Anthropic)
- Google-Extended
- PerplexityBot
- CCBot
Custom Allowlist
Section titled “Custom Allowlist”Add your own bots (one per line):
MyInternalBotPartnerCrawlerUptimeRobotForm Protection
Section titled “Form Protection”Protect WordPress forms from spam and automated submissions.
Forms Tab Settings
Section titled “Forms Tab Settings”| Setting | Default | Description |
|---|---|---|
| Comments | Yes | Check comment submissions |
| Login | Yes | Check login submissions |
| Registration | Yes | Check registration submissions |
| Honeypot Fields | Yes | Add invisible trap fields to those forms |
How Form Honeypots Work
Section titled “How Form Honeypots Work”<!-- Automatically injected hidden field (the name ends in comment, login or register) --><div style="position:absolute;left:-9999px;top:-9999px;"> <label for="webdecoy_hp_comment">Leave empty</label> <input type="text" name="webdecoy_hp_comment" id="webdecoy_hp_comment" value="" tabindex="-1" autocomplete="off"></div>| Scenario | Result |
|---|---|
| Human submits (field empty) | Submission allowed |
| Bot fills field | Detected as bot, blocked |
Login and Registration Protection
Section titled “Login and Registration Protection”On each login or registration submission the plugin checks the honeypot field and scores the request with the same server-side detector used everywhere else. When the score reaches Minimum Score to Block, the login or registration is refused with an error message (in monitor mode it is only recorded).
WooCommerce Protection
Section titled “WooCommerce Protection”If WooCommerce is installed, additional protection options appear. Start in monitor mode, inspect the evidence and test your own gateway and legitimate checkout flows before enabling enforcement.
Watch a controlled checkout test
Section titled “Watch a controlled checkout test”In an isolated WebDecoy 2.10.6 lab, three rapid $3 synthetic failed orders from one test IP were followed by a refused fourth checkout. We tested classic shortcode checkout and the Store API used by Checkout Blocks independently. Separate normal offline test orders completed on both paths. No real cards, processors or money were involved; this is a check of that pattern, not a production detection-rate benchmark.
See the test details and rollout guide · Install WebDecoy from WordPress.org
WooCommerce Tab Settings
Section titled “WooCommerce Tab Settings”| Setting | Default | Description |
|---|---|---|
| Checkout Protection | Yes | Enable checkout monitoring, including card testing detection |
| Honeytoken Coupon | Yes | A trap coupon code that only a bot would try |
| Velocity Limit | 5 per hour | Checkout attempts allowed per IP in the chosen window |
Card Testing Detection
Section titled “Card Testing Detection”Part of checkout protection. It looks at recent checkout attempts from the same IP:
| Pattern | Detection |
|---|---|
| 3 or more different cards | Card testing |
| 3 or more amounts under $5, across several orders or cards | Card testing |
| 3 or more declines, across several orders or cards | Card testing |
| More attempts than the velocity limit | Velocity abuse |
A shopper retrying a declined card on one order does not trip the order- and decline-based patterns on its own.
Checkout Velocity Limiting
Section titled “Checkout Velocity Limiting”IP: 192.168.1.100Checkouts this hour: 5Next checkout → BLOCKED (rate limit)What Gets Blocked
Section titled “What Gets Blocked”- IPs exceeding checkout velocity
- IPs matching the card testing patterns above
- Anyone who tries the honeytoken coupon
Client-Side Scanner
Section titled “Client-Side Scanner”The plugin includes a JavaScript scanner that runs in visitors’ browsers.
Scanner Tab Settings
Section titled “Scanner Tab Settings”| Setting | Default | Description |
|---|---|---|
| Enable Scanner | Yes | Load JavaScript scanner |
| Minimum Score to Report | 20 | Only report scores above this |
| Exclude Logged-In Users | No | Skip scanning for logged-in users |
What the Scanner Detects
Section titled “What the Scanner Detects”| Detection | Description |
|---|---|
| WebDriver | Selenium, Puppeteer automation |
| Headless Browser | Chrome Headless, PhantomJS |
| Browser Anomalies | Inconsistent navigator properties |
| AI Bots | GPTBot, ClaudeBot user agents |
Scanner Placement
Section titled “Scanner Placement”The scanner is enqueued automatically (public/js/webdecoy-scanner.js) with
its configuration passed via a localized webdecoyScanner JavaScript object.
There’s nothing to paste into your theme.
Excluding Visitors
Section titled “Excluding Visitors”Use the Scanner tab’s options (e.g. Exclude logged-in users and the minimum-score-to-report threshold) to control what the scanner reports.
Viewing Detections in WordPress
Section titled “Viewing Detections in WordPress”Dashboard Widget
Section titled “Dashboard Widget”The WebDecoy dashboard widget shows:
- Detections in the last 7 days, and how many were high risk
- Blocked IPs count
- A threat level breakdown
- Links to all detections and to blocked IP management
Detections Page
Section titled “Detections Page”Navigate to WebDecoy → Detections to view:
| Column | Description |
|---|---|
| Date | When detection occurred |
| IP Address | Visitor’s IP |
| Score | Threat score (0-100) |
| Level | MINIMAL, LOW, MEDIUM, HIGH, CRITICAL |
| MITRE Tactic | The tactic assigned to the detection |
| Actor Intel | Cross-site intelligence, when connected to WebDecoy Cloud |
| Source | Server detection, bot scanner, comment form, login form |
| User Agent | The request’s User-Agent |
| Actions | Per-row actions |
Filtering:
- By date range (today, 7 days, 30 days, all time, or custom dates)
- By threat level
- By source
You can also block selected IPs and export the filtered list as CSV.
Blocked IPs Page
Section titled “Blocked IPs Page”Navigate to WebDecoy → Blocked IPs to view:
| Column | Description |
|---|---|
| IP Address | Blocked IP |
| Reason | Why it was blocked |
| Blocked At | When block started |
| Expires | When block ends, or “Never (permanent)” |
| Blocked By | What created the block |
| Actions | Unblock button |
Managing Blocks:
- Click Unblock to remove a block immediately
- Expired blocks are automatically cleaned up
- Block an IP adds one by hand, for 1 hour, 24 hours, 7 days, 30 days, or permanently
Local vs. Cloud Detections
Section titled “Local vs. Cloud Detections”| Storage | Data |
|---|---|
| Local (WordPress DB) | All detections, for admin viewing |
| Cloud (WebDecoy) | Synced for dashboard analytics |
Troubleshooting the WordPress Plugin
Section titled “Troubleshooting the WordPress Plugin”Common Issues
Section titled “Common Issues”Every detection shows the same IP address
Section titled “Every detection shows the same IP address”Cause: the site is behind Cloudflare or another proxy, and no trusted proxy is configured. The plugin is reading the direct connection IP, which is the proxy.
Solution: configure the trusted proxy. Detections recorded before the fix keep the proxy’s address; only new ones resolve correctly.
Nothing is being blocked
Section titled “Nothing is being blocked”In order of likelihood:
- Monitor mode is on. It is the default. Check Settings → Blocking → Monitor mode and read the admin notice, which says how many requests enforcing would have acted on.
- A proxy is detected and not configured. The plugin withholds blocking on purpose in this state and shows a red notice saying so. See above.
WEBDECOY_DISABLEis defined inwp-config.php. The admin says “WebDecoy is disabled.”
Detection, logging and reporting continue in all three cases, so an empty block list next to a full Detections page is the expected picture rather than a fault.
API Status Shows “Inactive”
Section titled “API Status Shows “Inactive””Causes:
- Invalid API key
- Network connectivity issues
- API key expired or revoked
Solutions:
- Verify API key is correct
- Check for typos (no extra spaces)
- Generate a new API key if needed
- Check the server can reach
in.webdecoy.comandapi.webdecoy.com
Scanner Not Running
Section titled “Scanner Not Running”Causes:
- JavaScript errors on page
- Caching plugin conflict
- Theme blocking scripts
Solutions:
- Check browser console for errors
- Clear all caches (page, browser, CDN)
- Exclude scanner from optimization plugins
- Verify scanner is enabled in settings
Too Many False Positives
Section titled “Too Many False Positives”Causes:
- Sensitivity too high
- Score threshold too low
- Blocking legitimate bots
Solutions:
- Lower sensitivity to “Medium” or “Low”
- Increase minimum score to block (try 80)
- Add legitimate bots to allowlist
- Enable “Log Only” mode temporarily
WooCommerce Conflicts
Section titled “WooCommerce Conflicts”Causes:
- Checkout velocity too strict
- Interfering with payment plugins
Solutions:
- Increase max checkouts per hour
- Disable checkout protection temporarily
- Check for plugin conflicts
- Add payment gateway IPs to allowlist
Plugin Updates Not Showing
Section titled “Plugin Updates Not Showing”If you installed from the WordPress.org directory, updates arrive through WordPress itself: check Dashboard → Updates. There is no WebDecoy-specific control, and the self-updater described below is not present in that build.
For the CDN / self-hosted build:
Causes:
- CDN cache
- WordPress update check timing
Solutions:
- Go to Dashboard → Updates and click Check again
- The plugin caches the CDN update manifest for up to 12 hours, so a new release can take that long to appear
Error Logging
Section titled “Error Logging”The plugin writes API and forwarding errors to the PHP error log. To collect them in a file:
-
Add to
wp-config.php:define('WP_DEBUG', true);define('WP_DEBUG_LOG', true); -
Errors are then written to:
/wp-content/debug.log -
Look for entries starting with
WebDecoy
Getting Help
Section titled “Getting Help”If issues persist:
- Check plugin version is latest
- Gather debug logs
- Contact [email protected]