Skip to content

WordPress Plugin

The WordPress plugin is the fastest no-code path to server and browser detection on WordPress or WooCommerce.

Create a free account → · Compare all install methods

  1. In WordPress Admin, open Plugins → Add New.
  2. Search for WebDecoy, then choose Install Now → Activate.
  3. Open WebDecoy → Settings. Keep Monitor mode on while you review the first detections.
  4. Optionally open WebDecoy Cloud and connect the site to your WebDecoy dashboard.
  5. Send the reserved test request to prove the install end to end.

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.

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.

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
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 WebDecoy

The plugin requires WordPress 6.1 or later and is tested up to WordPress 7.0.

Section titled “Method 1: The WordPress.org directory (Recommended)”
  1. In WordPress Admin, go to Plugins → Add New
  2. Search for WebDecoy
  3. 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)”
  1. Download the Plugin

    • Go to https://cdn.webdecoy.com/wordpress/
    • Download the latest webdecoy-x.x.x.zip file
  2. Upload to WordPress

    • In WordPress Admin, go to Plugins → Add New
    • Click Upload Plugin
    • Choose the downloaded ZIP file
    • Click Install Now
  3. Activate

    • Click Activate Plugin
    • You’ll see “WebDecoy” in the admin menu
  1. Download and Extract

    Terminal window
    unzip webdecoy-x.x.x.zip
  2. Upload via FTP

    • Upload the webdecoy folder to /wp-content/plugins/
  3. Activate in WordPress

    • Go to Plugins in WordPress Admin
    • Find “WebDecoy” and click Activate

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.”

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:

Terminal window
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.


  1. Click WebDecoy in the WordPress Admin menu
  2. Click Settings
  3. Configure options across multiple 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:

  1. 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.
  2. 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.
  3. 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.

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.

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.

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.

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.


Configure how the plugin detects and responds to threats.

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
Level Behavior
Low Minimal detection, very few false positives
Medium Balanced detection and accuracy (recommended)
High Maximum detection, may have false positives
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, so nothing automated can complete it. On a tripwire that is the intent, since those paths exist nowhere on your site.

On Settings → Blocking, Block Duration is in hours, and 0 means permanent.

The default is 1 hour, changed from 24 in 2.3.2: 93% of hostile addresses are gone within the hour, so a longer default caught almost nothing and mostly risked blocking whoever inherited the address 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.


Configure which bots are allowed through without detection.

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
  • Googlebot
  • Bingbot
  • Yahoo! Slurp
  • DuckDuckBot
  • Baiduspider
  • YandexBot
  • Facebook External Hit
  • Twitterbot
  • LinkedInBot
  • Pinterest
  • WhatsApp
  • Slackbot
  • GPTBot (OpenAI)
  • ClaudeBot (Anthropic)
  • Google-Extended
  • PerplexityBot
  • CCBot

Add your own bots (one per line):

MyInternalBot
PartnerCrawler
UptimeRobot

Protect WordPress forms from spam and automated submissions.

Setting Default Description
Protect Comments Yes Add honeypot to comment forms
Protect Login Yes Detect brute force on login
Protect Registration Yes Catch fake registrations
Inject Honeypot Fields Yes Add invisible trap fields
<!-- Automatically injected hidden field -->
<input type="text"
name="website_url"
style="position:absolute;left:-9999px;height:0;width:0;overflow:hidden"
tabindex="-1"
autocomplete="off">
Scenario Result
Human submits (field empty) Submission allowed
Bot fills field Detected as bot, blocked
  • Tracks failed login attempts per IP
  • Temporary blocks after threshold
  • Detects credential stuffing patterns
  • Analyzes registration timing
  • Honeypot field validation
  • Email domain verification

If WooCommerce is installed, additional protection options appear.

Setting Default Description
Checkout Protection Yes Enable checkout monitoring
Max Checkouts Per Hour 5 Velocity limit per IP
Card Testing Detection Yes Detect rapid card attempts
Decline Tracking Yes Track payment failures

Detects patterns indicating card testing attacks:

Pattern Detection
Multiple cards, same IP Card testing
Rapid checkout attempts Velocity abuse
Many declines, one session Card stuffing
Small amounts, high volume Testing pattern
IP: 192.168.1.100
Checkouts this hour: 5
Next checkout → BLOCKED (rate limit)
  • IPs exceeding checkout velocity
  • Sessions with suspicious patterns
  • Known fraudulent payment patterns

The plugin includes a JavaScript scanner that runs in visitors’ browsers.

Setting Default Description
Enable Scanner Yes Load JavaScript scanner
Run on All Pages Yes Scanner on every page
Minimum Score to Report 20 Only report scores above this
Exclude Logged-In Users No Skip scanning for logged-in users
Detection Description
WebDriver Selenium, Puppeteer automation
Headless Browser Chrome Headless, PhantomJS
Browser Anomalies Inconsistent navigator properties
AI Bots GPTBot, ClaudeBot user agents

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.

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.


The WebDecoy dashboard widget shows:

  • Total detections (last 7 days)
  • Blocked IPs count
  • Recent high-risk detections
  • Quick links to settings

Navigate to WebDecoy → Detections to view:

Column Description
Date/Time When detection occurred
IP Address Visitor’s IP
Score Threat score (0-100)
Level MINIMAL, LOW, MEDIUM, HIGH, CRITICAL
Source Server, Scanner, Form
Action What action was taken

Filtering:

  • By date range
  • By threat level
  • By source type
  • By IP address

Navigate to WebDecoy → Blocked IPs to view:

Column Description
IP Address Blocked IP
Reason Why it was blocked
Blocked At When block started
Expires At When block ends
Actions Unblock button

Managing Blocks:

  • Click Unblock to remove a block immediately
  • Expired blocks are automatically cleaned up
  • Manual blocks don’t expire unless configured
Storage Data
Local (WordPress DB) All detections, for admin viewing
Cloud (WebDecoy) Synced for dashboard analytics

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.

In order of likelihood:

  1. 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.
  2. 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.
  3. WEBDECOY_DISABLE is defined in wp-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.

Causes:

  • Invalid API key
  • Network connectivity issues
  • API key expired or revoked

Solutions:

  1. Verify API key is correct
  2. Check for typos (no extra spaces)
  3. Generate a new API key if needed
  4. Check server can reach ingest.webdecoy.com

Causes:

  • JavaScript errors on page
  • Caching plugin conflict
  • Theme blocking scripts

Solutions:

  1. Check browser console for errors
  2. Clear all caches (page, browser, CDN)
  3. Exclude scanner from optimization plugins
  4. Verify scanner is enabled in settings

Causes:

  • Sensitivity too high
  • Score threshold too low
  • Blocking legitimate bots

Solutions:

  1. Lower sensitivity to “Medium” or “Low”
  2. Increase minimum score to block (try 80)
  3. Add legitimate bots to allowlist
  4. Enable “Log Only” mode temporarily

Causes:

  • Checkout velocity too strict
  • Interfering with payment plugins

Solutions:

  1. Increase max checkouts per hour
  2. Disable checkout protection temporarily
  3. Check for plugin conflicts
  4. Add payment gateway IPs to allowlist

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:

  1. Go to Plugins → WebDecoy
  2. Click Check for updates
  3. Or wait for automatic check (every 12 hours)

Enable debug logging:

  1. Add to wp-config.php:

    define('WEBDECOY_DEBUG', true);
  2. Logs are written to:

    /wp-content/debug.log
  3. Look for entries starting with [WebDecoy]

If issues persist:

  1. Check plugin version is latest
  2. Gather debug logs
  3. Contact [email protected]