ReportedIP Hive 2.0.15 — Multi-Recipient Mail Relay & Stronger Hardening Mode
ReportedIP Hive 2.0.15 is out. This release closes a class of silent-failure bugs around alert delivery, attack-pattern deduplication, and quota handling on unlimited tiers. If your site is on a public WordPress install or behind a reputation-driven WAF, you should upgrade.
Upgrade path: the in-plugin updater (Plugin Update Checker, v5.6) polls GitHub Releases every 12 hours. To force the check, visit Dashboard → Updates on your site, or download the latest ZIP from the official release page.
What changed in 2.0.15
Multi-recipient admin notifications no longer get dropped
The managed mail relay (POST /reportedip/v2/relay-mail on the ReportedIP service) validates a single address per request via sanitize_email + is_email. Hive used to build the recipient field as implode(', ', $recipients), which the relay then rejected with HTTP 422 — and the whole alert was dropped. The site logged mail_failed, the admin never saw the notification, and there was no obvious clue why.
ReportedIP_Hive_Mailer::send() now detects a comma-separated to field, splits it via split_recipients(), and dispatches one mail per address through the same provider stack via dispatch_one(). Local wp_mail() fallback is unaffected — it accepts comma-lists natively, and the split path stays consistent across providers.
The 14-day per-event cooldown still applies to the first recipient — once the cooldown fires, the remaining recipients in the same call all benefit from the same set_transient() slot. That matches the legacy behaviour and avoids N× cooldown bookkeeping per delivery.
Hardening Mode no longer re-activates against the same attack pattern every hour
Security_Monitor::check_coordinated_attacks() runs against a rolling 2-hour lookback in wp_reportedip_hive_attempts. A single attack pattern (for example, 10 IPs hammering 20 failed logins inside one minute) used to trigger a full Hardening Mode re-activation on every hourly cron sweep until the row aged out. The Activity log filled up with duplicate hardening_mode_activated entries, and the actual trigger payload kept getting overwritten by weaker follow-ups.
Hardening_Mode::activate() in class-hardening-mode.php now writes a per-time-window suppression marker (reportedip_hive_hardening_seen_<md5>) at activation. Later calls that present the same window short-circuit unless the candidate reason is strictly more severe. The marker TTL tracks the configured Hardening duration plus 24 hours.
TTL-low extensions are now a separate code path. When the remaining TTL is under 50 % of the configured duration and the candidate reason is not stronger, the activation extends TRANSIENT_UNTIL only and emits hardening_mode_extended at severity low. The original stronger reason stays in TRANSIENT_REASON and on the UI.
Quota status no longer freezes the report queue on unlimited tiers
Enterprise and Honeypot tiers used to hit the queue’s no_quota short-circuit when the upstream stamped remaining_reports = 0 on what was actually an unlimited account — a transient server-side glitch in the quota refresh could silently freeze the API report queue for the rest of the day.
get_quota_status() in class-api-client.php now detects unlimited tiers via daily_report_limit < 0 || === null and forces remaining = -1, matching the >= 0 guard in process_report_queue().
Relay 429 backoffs are now respected client-side
A 429 response from POST /reportedip/v2/relay-mail (server-side progressive backoff per recipient) previously only triggered the per-call wp_mail() fallback. The next security alert immediately attempted another HTTP call, so the same recipient could see dozens of 429s per day in the logs.
relay_request() in class-api-client.php now stores time() + retry_after in a per-(endpoint, recipient) transient, short-circuits subsequent calls inside the cooldown to a client_backoff soft-failure, and clears the cooldown on the first successful response. The mail and SMS providers still fall back transparently — the difference is that the client now stops spamming the relay until the backoff window expires.
Decoy bait paths expanded from 16 to 40
Earlier in the 2.0 line we expanded the decoy bait-path list. Hive’s Decoy Surface now serves 404-trap responses for: the full wp-config.php.* backup family (.bak, .old, .save, .orig, .swp, .txt, trailing ~); more .env* backups; Joomla configuration.php.bak; common SQL dumps at the webroot (dump.sql, database.sql, backup.sql, db.sql); Apache .htpasswd and .htaccess.bak; cloud credentials (.aws/credentials, .aws/config); SSH keys (.ssh/id_rsa, .ssh/authorized_keys); and private-key files at the webroot (id_rsa, private.key, server.key).
Any request for one of these paths is now a high-confidence attacker signal and feeds the community reputation database when you run Hive in Community Network mode.
Upgrade
- In-plugin auto-update. The Plugin Update Checker polls GitHub Releases every 12 hours. Force a check via Dashboard → Updates if you don’t want to wait.
- Manual download. Grab the latest ZIP from github.com/reportedip/reportedip-hive/releases.
- WP-CLI.
wp plugin update reportedip-hiveif you manage WordPress via CLI.
Full changelog
For the complete version history including 2.0.14, 2.0.13 and earlier, see the API and Plugin changelog.