Skip to main contentSkip to footer

Firewall and WAF

Hive inspects requests in two places that behave the same: an engine inside WordPress and an optional guard that runs before WordPress loads. The rules are not written into the plugin but delivered signed from reportedip.com, with a bundled baseline that always works offline. The engine is free on every plan.

The engine inside WordPress

On init at priority 1 the engine matches the active ruleset against the URI, the query string, the request body (also in a decoded copy) and the user agent: SQL injection, cross-site scripting, path traversal, command injection, file inclusion wrappers, SSRF, Log4Shell, PHP object injection, XXE, web shell uploads, CRLF and template injection, scanner user agents. A hit ends in the shared 403 block page.

  • Safe by construction: bounded regular expressions, a malformed rule is skipped, and an error lets the request through instead of taking the site down.
  • No false alarms for your editors: signed-in users who may edit content, wp-admin, cron and WP-CLI are not inspected by the engine; the whitelist always wins.
  • Report-only: the firewall can log what it would block (waf_would_block) without blocking.
  • Where: engine, mode and Paranoia Level under Protection → Firewall & Bots; rule sync and exceptions on Tools → Rules; the firewall log on Activity.

Signed rule delivery and Priority Sync

Rulesets come versioned and Ed25519-signed from reportedip.com. The plugin checks every ruleset against a public key it ships with and keeps the bundled baseline when a feed is missing, too large or does not verify, so a tampered feed cannot change your rules. New signatures reach every connected site within hours, without a plugin release.

PlanRulesRefresh
Local Shield, any planBundled OWASP Top 10 baseline, Paranoia Level 1With the plugin updates
Free, Community NetworkServer ruleset at Paranoia Level 1, which covers more than the bundled oneEvery six hours
ContributorPriority Sync: Paranoia Level 2 and the bot address range feedsWeekly
Professional and upPriority Sync: Paranoia Level 3, bot ranges, the live list of disposable mail domainsDaily

Paranoia Level 3 is strict and catches obfuscated payloads, at the price of more false positives; it is meant for experienced operators. Contributor is a free plan for accounts that contribute data, for example through a honeypot or the Linux agent.

Extended Protection: the guard before WordPress

An optional auto_prepend_file guard applies the same rules, exceptions, whitelist and IP blocks before WordPress loads, so a blocked request costs almost nothing. Its hits are written to a queue and imported into the log and the escalation ladder; a block set by the plugin reaches the guard within the same request. The guard is off by default and set up on Tools → Server:

  • Apache and PHP-FPM (also nginx with PHP-FPM) are configured automatically through .htaccess or a .user.ini in the document root.
  • Other stacks get the line for php.ini or the hosting panel, or an nginx fastcgi_param snippet.
  • Signed-in users: the guard skips body inspection when a WordPress sign-in cookie is present, so saving content never trips it; URL and user agent rules still apply.
  • Status you can trust: the Server tab reports whether the guard really ran for the current request, and the readiness register warns when its queue is not writable.
  • Fail-open and safe to remove: any error lets the request through. Switching it off removes the directives Hive controls and leaves an inert placeholder file, so a leftover line in a hand-edited configuration never points at a missing file. Report-only mode switches the guard off as well.

Exceptions for false positives

A form that accepts HTML, a page builder posting raw markup or an API receiving attack samples can trip a signature now and then. An exception lets that one case pass while the rest stays protected.

  • Where: Tools → Rules → WAF Exceptions, or Allow on a firewall row in the log, which fills in a narrow exception for exactly that rule on that path.
  • Scope: one rule, a rule group or, for an endpoint of your own, the whole engine on a path, optionally narrowed to an address or range. A whole-engine exception always needs a path or address, so the firewall can never be switched off globally by accident.
  • Keep it narrow: a rule on a path before a group, a group before the whole engine. The log row shows the matched value, the inspected part, method, URI and user agent, and for admin-ajax.php the AJAX action.
  • Both layers: exceptions are baked into the guard and rebuilt whenever the list changes. On a network they apply to all sites. Every plan.
  • In code: the filter reportedip_hive_waf_bypass_routes excludes REST routes by an anchored prefix on the resolved route; it works in the engine only.

Reference codes and the block page

Every block, firewall or sensor, carries a code such as WAF_SQLI-3F9A2B71 on the block page and in the X-RIP-Ref header. A visitor who was blocked by mistake quotes the code, and you find the row in the log. The code is a one-way hash of address, reason and hour, so it reveals nothing. The texts of the block page can be replaced with the filter reportedip_hive_blocked_page_strings.

Page caches

The block page defines DONOTCACHEPAGE, DONOTCACHEDB and DONOTCACHEOBJECT and sends Cache-Control: no-store, no-cache, must-revalidate, max-age=0, Pragma: no-cache and the WordPress nocache_headers(). WP Rocket, W3 Total Cache, WP Super Cache and LiteSpeed Cache respect this, so one blocked attacker never leaves a cached 403 for real visitors. The form check carries nothing request-specific, so cached pages keep working with it.

Last updated: · Maintained by the ReportedIP team

Security Focused
GDPR Compliant
Made in Germany
Back to Docs