Bot Protection: Machines, Not Humans
A "bot" is a program that accesses your website automatically without human interaction. Some bots are good (Google), others are malicious (spam, scraping, attacks).
SeenSecure's Bot Protection detects whether what's accessing your site is really a human or a machine. If it's a malicious bot, it blocks it. If it's a good bot (Googlebot), it lets it through.
Types of Bots
Legitimate Bots (Allowed)
| Bot | Purpose | Benefit |
|---|---|---|
| Googlebot | Indexes for Google Search | Your site appears on Google |
| Bingbot | Indexes for Bing Search | Your site appears on Bing |
| Facebook Crawler | Fetches metadata for sharing | Links on Facebook show a preview |
| Slack Bot | Fetches metadata for Slack | Links in Slack show info |
Malicious Bots (Blocked)
- Scrapers: Copy your content
- Brute Force Bots: Automatically try passwords
- Spam Bots: Post spam in comments
- DDoS Bots: Send thousands of requests to bring down the site
- Malware Bots: Search for vulnerabilities
- Proxy-Rotating Bots: Hide their identity to evade blocks
Ambiguous Bots (Depends on Context)
Some bots aren't clearly good or bad. Example:
- Pingdom: Legitimate uptime monitoring
- Generic Crawlers: Could be research or malicious
- SEO Tools: Analysis tools (legal but aggressive)
Layer 1: Identity Filtering
The first layer doesn't analyze behavior or wait to see what the visitor does — it judges based on what the request says about itself, before WordPress even loads. It's the cheapest to run (no database queries, no calculations), which is why it goes first: it discards obviously automated traffic in microseconds, leaving the more expensive layers to deal only with what's already passed this first filter.
User-Agent Blocklist
Every visitor (human or machine) sends a User-Agent header stating what software it's using. A real browser sends something like Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36. Many automated scraping and attack tools, on the other hand, use their real name without disguising it — either because whoever coded them never thought to hide it, or because changing the User-Agent in some tools requires extra configuration almost nobody bothers with.
Real browser: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Legit bot: Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
Tool: python-requests/2.25.1
Tool: curl/7.68.0
Tool: Scrapy/2.5.0 (+https://scrapy.org)
Empty: (no User-Agent header at all)
SeenSecure maintains a list of 21 known signatures for scanning and pentesting tools (sqlmap, Nikto, Nmap, masscan, Metasploit, Hydra, etc.) and blocks the request as soon as the User-Agent matches — before spending any other resources analyzing it.
HTTP/1.0 Blocking
HTTP has several protocol versions. HTTP/1.0, from 1996, is the oldest and virtually no modern browser uses it anymore — Chrome, Firefox, Safari, and Edge automatically negotiate HTTP/1.1, HTTP/2, or HTTP/3 with the server. If a real request arrives announcing itself as HTTP/1.0, it's almost certainly not coming from an actual browser, but from a simple script built with a minimal library that never updated its default protocol version.
Missing or Inconsistent Language Header
A real browser always sends the Accept-Language header, indicating which language it prefers to receive content in (set by the operating system or browser itself). A hand-written script almost never bothers to add it — nobody who's only trying to extract data or test for vulnerabilities cares what language the server responds in. Its total absence is therefore a strong signal of non-human traffic.
And it's not just the absence that matters: the declared language is also compared against the IP's country of origin (via geolocation). A visitor claiming to prefer "zh-CN" (Chinese) but connecting from a residential IP in a country where that language is rare is a typical pattern of traffic routed through a poorly configured proxy or VPN — it doesn't prove anything on its own, but it adds suspicion points alongside the rest of this layer's signals.
Anti-Bot URL Exclusions (External Crons and Scripts)
/planning/daily_script.php every night, a payment-provider webhook, a sync script, etc. These requests don't send the Accept-Language header (or others a real browser sends), so Layer 1 mistakes them for bots and blocks them. This field lets you tell the firewall: «don't apply Anti-Bot to these specific paths, they are legitimate».
/.
How to Identify Exactly Which Path to Exclude
- Open Firewall › Logs › Traffic Log and find the blocked row (reason «No Language»).
- Copy the path part from the Request column, e.g.
/planning/daily_script.php. - Paste it into the «Anti-Bot URL exclusions» field, one path per line, and save Layer 1.
Wildcard * is supported (e.g. /cron/* excludes everything under /cron/) and prefix matching (/webhook/ covers any URL starting that way). /wp-cron.php is already excluded by default.
How Security Remains
WAF, rate limiting, IP lists, DNS crawler verification and login validation still protect that URL. Only the automated Layer 1 check is relaxed.
No Slowdown
Exclusions are checked in milliseconds against an in-memory list. No impact on your site's performance.
Layer 2: Browser Fingerprint
A more sophisticated attacker doesn't use a simple curl script — they use a headless browser (real Chrome or Firefox, but controlled by code instead of a human, with no visual interface) precisely to sail through Layer 1: the User-Agent is identical to a normal Chrome's, the HTTP version is correct, and it can even send Accept-Language. Layer 2 exists to catch exactly this case, by looking at browser properties that automation software leaves exposed even when trying to pass as a normal browser.
How it works: when a visitor loads a protected page, a small script in the browser collects a handful of technical characteristics — whether it responds to Canvas and WebGL (graphics) requests, which plugins are installed, the real screen resolution, the order HTTP headers arrive in, and how quickly it reacts. Each one adds or subtracts from a score out of 100: a normal human with a real browser scores high; a headless browser with no graphical interface fails several of these checks at once and scores low.
How to Enable and Configure It
SeenSecure > Firewall > Anti-Bot > Layer 2: Bot Fingerprint Analyzer > Enabled
| Field | What it does |
|---|---|
| Action on bot detection | Log only, force a CAPTCHA, or block access outright |
| Minimum score | Slider from 0 to 100: visitors below this threshold are treated as suspicious |
| Check on | Login page and/or frontend (comments, public forms) |
| Detection modules | 5 independent switches: Headless Detection, Canvas Fingerprint, WebGL Renderer, Timing Analysis, Feature Detection |
Layer 2+: Advanced Human Behavior Detection (PRO)
How it works: a real person's mouse moves irregularly, with small corrections and pauses — never in a perfectly straight line. When typing, there are natural rhythms between keystrokes that are never perfectly even. An automated script, by contrast, usually moves the mouse in a straight line to the field (or doesn't move it at all) and types with an almost identical interval between keystrokes every time. These signals add to the same score already calculated by Layer 2 — it isn't an independent score or action.
How to Enable It
SeenSecure > Firewall > Anti-Bot > Layer 2+: Advanced Human Behavior Detection > Enabled
Once enabled, it adds to the Layer 2 score: if the behavior looks suspicious, the score drops and the same action (log, CAPTCHA, or block) already configured on Layer 2 applies — there's no separate setting to configure.
Layer 3: Crawler Verification
Anyone can put "Googlebot" in their User-Agent — it's just text, there's no automatic check preventing it at the protocol level. Many malicious bots do exactly that, pretending to be Googlebot or Bingbot to try to get the firewall to wave them through without further questions, banking on the fact that many sites blindly trust that name.
SeenSecure verifies the real identity with an industry-standard technique: reverse DNS. When a request claims to be Googlebot, the system resolves the actual domain name associated with that IP address (Google, for example, always resolves to a domain ending in .googlebot.com or .google.com) and, if it matches, performs a second check in the opposite direction (forward DNS from that domain back to the IP) to confirm it wasn't spoofed. Only if both checks match is the request trusted as genuinely coming from Google.
How to Configure Bot Protection
Step 1: Enable Protection
SeenSecure > Firewall > Bot Protection > Enable
Step 2: Choose Protection Level
- Permissive: Only blocks obviously malicious bots. Googlebot passes without a CAPTCHA
- Moderate (Recommended): Detects suspicious bots, may ask some for a CAPTCHA
- Aggressive: Every unrecognized bot = CAPTCHA. Even Google must prove itself
Step 3: Define Behavior on Detection
- Block: Rejects immediately (403 error)
- Challenge: Requires solving a CAPTCHA
- Log: Only saves to the log, allows access (debug)
Step 4: Allow Specific Bots (Whitelist)
If there are legitimate crawlers you want to allow without a CAPTCHA:
Whitelist:
- Googlebot
- Bingbot
- facebookexternalhit
- Slurp (Yahoo)
Step 5: Block Specific Bots (Blacklist)
If you know of specifically malicious bots:
Blacklist:
- MJ12Bot (malicious SEO bot)
- DotBot (scraper)
- AhrefsBot (aggressive)
Layer 4: robots.txt Control and XML Sitemap
This layer doesn't block anything by itself — it's a set of instructions telling search engines (Google, Bing) which parts of your site they're allowed to crawl. It complements the other layers: while Layers 1-3 detect malicious bots that ignore the rules, Layer 4 organizes the behavior of legitimate bots that actually follow them.
robots.txt Editor
In Firewall > Anti-Bot > Layer 4, enable "Customize robots.txt" and choose between:
- Preset templates: ready-made configurations for common cases (block /wp-admin/, allow everything, block everything, etc.), usable without writing a single line
- Custom directives: you choose yourself, checkbox by checkbox, which parts of WordPress to block from search engines (admin area
/wp-admin/, internal files/wp-includes/, REST API/wp-json/and/?rest_route=, or/xmlrpc.php)
XML Sitemap Generator
On the same screen, enable "Serve sitemap.xml generated by SeenSecure" to publish a complete map of your site at yoursite.com/sitemap.xml — the file search engines use to discover all your pages at once, instead of having to find them by following links one by one.
| Option | What it does |
|---|---|
| Exclude blocked routes | The sitemap doesn't include pages you've already marked as blocked in the robots.txt directives above |
| Cache (seconds) | How long the generated sitemap is kept before recalculating it. No need to wait: it regenerates itself automatically every time you publish or update content |
| Additional paths | URLs that aren't WordPress pages/posts but you still want included (one per line; full external URLs are also accepted) |
Layer 5: Strict IP Validation (Anti-Spoofing)
This layer isn't a new limit — it protects all the others. Rate limiting, login lockouts, geo-blocking, IP lists... all of those protections decide what to do based on the visitor's IP address. The problem: there are HTTP headers (X-Forwarded-For, X-Real-IP, CF-Connecting-IP) that a visitor can fake by hand to pretend to be a different IP than the real one behind their connection — and if the firewall trusts those headers blindly, all your IP-based counters and blocks can be dodged just by lying about your own IP.
Layer 6: Mass 404 Scan Protection
What it's for: when the same visitor requests, one after another within a few minutes, many pages that don't exist on your site, it's a very reliable sign they're scanning for weak points — no human browses that way, and no legitimate search engine bot (Google, Bing) generates that pattern. This layer counts those 404 errors per IP and cuts the scan short before it finishes.
Why an attacker attempts it: automated scanning tools (like Nuclei or Nikto) try dozens or hundreds of known paths in seconds — /wp-config.php.bak, /.env, /database.sql, /admin.php — looking for some sensitive file left accessible by mistake. It's a reconnaissance step before a real attack: the more paths it tries, the higher the chance of finding something exploitable.
How it works: for each IP, the plugin counts how many 404 pages it requests within the configured time window. If it exceeds the threshold, that IP is blocked for the configured duration (or just logged, depending on the chosen action). Like the rest of the firewall, this layer respects the global mode: in Monitor it only logs, never blocks; in Protection/Strict it applies the configured action. You can exclude paths that generate legitimate 404s (favicon.ico, robots.txt, etc.) so they don't count toward the threshold.
Configuration
| Field | What it does | Default |
|---|---|---|
| 404 Threshold | Number of not-found pages that trigger the block | 12 |
| Time Window | Period during which 404s are counted | 5 min |
| Block Duration | Time the IP remains blocked | 10 min |
| Action | Block IP (403) or log only | Block |
Private Mode
A switch built for sites that should not appear in any search engine: intranets, staging environments, websites under construction, or private projects. Turning it on from Firewall > Anti-Bot does three things at once:
robots.txtswitches to blocking everything (Disallow: /), regardless of your Layer 4 configuration- Every page sends the
X-Robots-Tag: noindex, nofollowheader, the direct signal that tells a search engine "don't keep me in your index or follow my links" - The firewall blocks any detected bot, including legitimate search engines like Google or Bing — no exceptions
Best Practices
For Public Sites (Blog, Store)
- Use "Permissive" level
- Leave Googlebot and Bingbot without a CAPTCHA (you need indexing)
- Block known scraper bots
For Private Sites (Admin, Community)
- Use "Aggressive" level
- Require a CAPTCHA for all initial access
- Whitelist only employee IPs (no bots)
For E-commerce (Online Store)
- "Moderate" level
- Aggressively protect checkout (Aggressive on /checkout)
- The public can browse without a CAPTCHA
Interpreting Logs
- Bot = Googlebot, asked for CAPTCHA: It's not the real Googlebot, it's fake. Block it.
- Empty User-Agent + suspicious headers: Clearly malicious.
- Legitimate bot blocked: Check whether it's a false positive, whitelist it if legitimate.
🔧 Troubleshooting
A legitimate visitor got blocked or keeps getting a CAPTCHA
This is the most common false-positive symptom. Before changing anything, confirm the real cause in Firewall → Traffic Log: look up the IP or approximate time and check the "PROTECTION" column — it tells you exactly which layer acted, don't assume it was Bot Protection without checking.
- If it was Layer 2 (Fingerprint) or Layer 3 (Crawler verification): on its own card, under Firewall → Anti-Bot, each one has an action dropdown with a 📝 "Log only" option — switch it there temporarily instead of turning the whole layer off: you keep seeing in the Traffic Log what it would have blocked, without locking anyone out while you adjust it.
- If it was Layer 5 (Strict IP Validation): that layer's own card already warns about the most typical cause: some corporate or mobile-carrier proxies rewrite the X-Forwarded-For header on legitimate connections. If you turned on the extra "🚫 Block spoofing IP" switch there, turn it off first — you can keep validation on (it still corrects the IP your counters use) without the hard block.
I need to unblock someone right now
Add them directly under Firewall → IP Lists (whitelist): it takes absolute priority over any Anti-Bot layer, including Layer 2+. No need to wait for the block to expire or touch that layer's configuration.
Frequently Asked Questions
Does it slow down my site with CAPTCHA? Only if a visitor is detected as a bot. Humans get through without a CAPTCHA normally.
Can I allow Googlebot but block other bots? Yes, that's ideal. Whitelist Googlebot/Bing, blacklist the rest.
What happens if legitimate users are flagged as bots? They're asked to solve a CAPTCHA. If it happens frequently, reduce the aggressiveness.
Are RSS feeds affected? No, RSS is different. But some readers may be detected as bots (this is normal).
What is the "First Line" mentioned in the Rate Limiting panel? It's a separate protection layer, not specific to bots: it acts before WordPress even loads, to stop traffic spikes or attacks too large or fast for the rest of the plugin to react to. It's enabled and configured under Firewall → Rate Limiting → "🚀 First Line". As part of that protection, and to avoid hurting your search rankings, it also checks that a visit claiming to be a legitimate search engine or AI assistant really is one before applying any limit — it's not enough for the request to just say so: it's cross-checked against the relevant company's official data, so no one gets through by just changing a header.
Does Layer 2+ (Human Behavior) only work on login and registration? By default yes, because that's where it matters most (a genuine search bot browses and reads, it never tries to log in). You can extend it to "any form on the site" from its own card under Firewall → Anti-Bot if you also want to protect a contact form or similar.
What's the difference between blocking and "log only" on each layer? "Log only" lets you see in the Traffic Log what that layer would have blocked, without affecting any real visitor — useful for testing a new layer before turning it on for real.
Can I disable a single layer and leave the rest active? Yes, each of the 6 layers (and Layer 2+) is enabled/disabled independently; none of them depend on the others to work.
Does raising the aggressiveness hurt my Google ranking? It shouldn't: Googlebot and other legitimate search engines/AI assistants are verified by reverse DNS (Layer 3) and official lists, not by what their headers claim — they keep getting through even as the rest of your traffic gets stricter.