Inside the ReportedIP Hive Web Application Firewall
ReportedIP Hive ships a Web Application Firewall that reads every request before WordPress acts on it. It matches the URL, query string, request body and user-agent against a signed ruleset, blocking SQL injection, XSS, path traversal, command injection and a dozen other attack classes — and the rules update themselves without a plugin release.
The engine and its baseline ruleset are free on every plan. This guide covers how the firewall inspects traffic, where the rules come from, how a bad regex is stopped from taking the site down, how to clear a false positive from the admin, and how the optional pre-WordPress guard works. It reflects Hive as of version 2.1.21, after the 2.1.5–2.1.21 hardening run.
What the WordPress firewall inspects on every request
The WAF runs on the init hook at priority 1, immediately after Hive’s IP-block check. A request from an already-blocked IP never reaches the firewall, so there is no wasted work. Everything else is inspected: the request URI, the query string, the request body and the user-agent are flattened and matched against the active ruleset.
The cost is about 4 microseconds of CPU per request with zero extra database queries when a persistent object cache is present. Matched attack classes include SQL injection, cross-site scripting, path traversal, command injection and LFI wrappers, plus SSRF, Log4Shell/JNDI, PHP object injection, NoSQL injection, XXE, web-shell uploads, CRLF and template injection — each with its own block reason code.
The inspection is read-only and false-positive-aware. Logged-in administrators are exempt (admins legitimately paste SQL and code into editors), /wp-admin is never inspected, and whitelisted IPs are skipped. A hit is blocked through the same cache-safe, reference-coded 403 path the other sensors use, or merely logged when report-only mode is on.
Why the firewall rules live on a server, not in the plugin
Most WordPress firewalls hard-code their signatures, so every rule update needs a plugin release. Hive does it the other way around: the signatures come from the reportedip.de Rule API as versioned, Ed25519-signed, tier-staggered rulesets, synced every six hours. New attack signatures reach every install within hours.
There are four rulesets — waf, bot_signatures, disposable_domains and scan_paths. Each is signed with a detached Ed25519 signature, and the plugin verifies it against a bundled public-key set (current plus next, for rotation) before applying it. If verification fails, the feed is oversized, or the server is unreachable, Hive falls back to a bundled baseline ruleset. A tampered or hijacked feed cannot poison the rules — even if an API key leaks or TLS is broken.
The baseline ships inside the plugin, so the firewall works fully offline in Local Shield mode with no account and no outbound calls. The rule sync is opt-in: it only runs in Community mode with an API key set.
Free baseline, deeper rules on Professional
The rule staggering follows the OWASP Core Rule Set Paranoia Level model, the de-facto WAF standard used by ModSecurity and Cloudflare.
| Paranoia Level | Character | Hive plan |
|---|---|---|
| PL1 | Baseline, tuned for minimal false positives, covers the OWASP Top 10 | Free (bundled baseline) |
| PL2 | More vigilant, a few more false positives | Contributor (weekly) / Professional |
| PL3 | Rare attacks, obfuscation and WAF-bypass coverage, occasional false positives | Professional (Priority Sync) |
Free gets a working, low-false-positive firewall — the protection promise. Professional adds the deeper, frequently-updated PL2/PL3 rulesets through Priority Sync, along with the live bot-IP-range and disposable-domain feeds.
How Hive stops a bad rule from taking your site down
Because the patterns arrive from a feed, a malformed regex is a first-class risk: catastrophic backtracking (ReDoS) once took Stack Overflow offline for 34 minutes. Hive guards against it in layers:
- Lower backtrack limit. Before the inspection loop Hive sets
pcre.backtrack_limitto 100,000 (down from the 1-million default) and restores it afterwards, capping the worst-case runtime per pattern. - Fail-open on a regex error. When a pattern hits the limit,
preg_match()returnsfalse, not0or1— a silent bypass if unchecked. Hive treatsfalseas fail-open plus a loggedwaf_pattern_errorevent. A broken rule never blocks legitimate traffic and never locks the site out: availability before strictness. - 8 KB body cap. Request bodies larger than 8 KB skip the body groups, so the backtracking base is bounded.
- Server-side linter. On reportedip.de, every pattern is checked for catastrophic backtracking before it is signed — a dangerous pattern is never shipped in the first place.
Curated patterns also favour atomic groups and possessive quantifiers, which are backtracking-free, and PCRE’s JIT (on by default in WordPress) speeds up matching.
Clear a false positive from the admin, without touching code
Any signature firewall will occasionally flag a legitimate first-party request — a page builder posting rich HTML, or a security plugin that legitimately ingests attack-like payloads. Since version 2.1.9, Hive handles this the way ModSecurity exclusions and the Wordfence allowlist do: a backend-managed exception list, no code and no report-only detour required.
- One click per log row. Every WAF block in the log carries an Allow action that creates a narrow exception for exactly that rule on that path. The block log records the matched value, the inspected target, the request method, URI, user-agent and paranoia level, so a decision is diagnosable without reproducing the request.
- Scoped, never global. An exception targets a single rule, a rule group, or — for a first-party endpoint — the whole engine on a path, optionally narrowed to an IP or CIDR. A whole-engine exception must carry a path or IP, so the firewall can never be switched off site-wide by accident.
- Network-wide and free. Exceptions are stored as network-wide data (option
reportedip_hive_waf_exceptions, schemadb_version10) and available on every plan — the protection engine itself stays free. - Applies to the pre-WordPress guard too. Extended Protection bakes the same exceptions in and rebakes them whenever the allowlist changes, so a client you allowed in the admin is honoured before WordPress even loads.
The exception form is self-explanatory: the scope selector reveals only the relevant field, and the ambiguous “Rule ID or group” input is split into a Rule ID field and a group dropdown populated from the engine’s known categories. Developers get a code-level escape hatch as well — the reportedip_hive_waf_bypass_routes filter, matched by an anchored str_starts_with test against the resolved REST route, so a bypass token in an unrelated query parameter cannot disable the WAF.
Extended Protection: blocking before WordPress loads
The init-hook firewall runs after WordPress has booted. For protection before any plugin code executes, Hive offers an optional drop-in that runs the WAF through PHP’s auto_prepend_file directive — the same approach Wordfence calls Extended Protection. It is off by default and additive to the in-WordPress engine, and it inspects request bodies just like the main engine (a hoisting bug that made body inspection a silent no-op was fixed in 2.1.10).
- Apache gets a
php_value auto_prepend_fileline written into a marked.htaccessblock. - PHP-FPM — including nginx. Hive detects the PHP-FPM SAPI ahead of the nginx server string and writes a document-root
.user.ini, which PHP-FPM honours for every request regardless of nginxlocationblocks. Since 2.1.17 this covers nginx automatically, with no manual step — earlier versions could only offer a hand-pastedlocationsnippet that protected just the one block it landed in. - Fallback snippet. On stacks without a FastCGI PHP SAPI, Hive still generates a copy-paste php.ini / PHP-FPM-pool line and an nginx
fastcgi_param PHP_VALUEblock; the Server Setup tab surfaces these whenever the auto-written.user.iniis not yet taking effect.
Three safety behaviours make the guard predictable. It skips body inspection for signed-in users — it detects the wordpress_logged_in cookie, so an editor saving a post through admin-ajax.php or the REST API is never tripped by an XSS/SQLi signature (URL and user-agent rules still run, and the in-WordPress engine stays the capability-aware backstop). It self-heals on toggle: disabling the WAF or switching it to report-only neutralises the pre-WordPress guard as well, so the firewall can never keep enforcing after it was switched off. And removal is fail-safe: deactivating the plugin strips the directives Hive controls and leaves an inert placeholder instead of deleting the guard file, so a leftover auto_prepend_file line in an nginx or php.ini config Hive cannot edit can never point at a missing file and 500 the site.
The setup is verifiable: the status reports whether the guard actually executed for the current request — “Setup complete” the moment it works — instead of guessing. The setup wizard walks new installs through it with safe defaults.
Reference codes turn a wrong block into a one-line lookup
Every block carries a correlatable reference code such as WAF_SQLI-3F9A2B71, shown on the block page and sent as the X-RIP-Ref header. A visitor who is blocked by mistake quotes one short string, and an admin matches it in the logs — then clears it with the one-click Allow action if it was a false positive. The token is a one-way hash of the IP, the reason and the hour, so it exposes no personal data.
Frequently asked questions
Is the Web Application Firewall free?
Yes. The WAF engine and the OWASP-Top-10 Paranoia-Level-1 baseline run on every plan, including the free tier and the fully offline Local Shield mode. Professional adds the deeper Level 2/3 rulesets and live feeds through Priority Sync.
Will the firewall block my own admin work?
No. Logged-in administrators are exempt, /wp-admin is never inspected, and the pre-WordPress guard skips body inspection for any signed-in user. If a front-end form or a first-party endpoint does trip a rule, open the WAF log, click Allow on that row to create a narrow exception, and you are done — no code and no report-only detour needed.
Does the firewall run on nginx?
Yes, and since 2.1.17 the pre-WordPress guard configures itself on nginx automatically by writing a document-root .user.ini that PHP-FPM honours for every request. If your stack disables per-directory INI files, the Server Setup tab shows a php.ini or nginx fastcgi_param line to paste instead.
What happens if the rule server is unreachable?
Nothing breaks. The plugin keeps using the last verified ruleset, or the bundled baseline, and retries the sync later. The firewall never depends on a live connection to work.