Linux 软件免费装
Banner图

Init Void Shield – Zero-DB, Honeypot, Anti-Spam

开发者 brokensmile.2103
更新时间 2026年9月8日 22:04
PHP版本: 7.4 及以上
WordPress版本: 7.1
版权: GPLv2 or later
版权网址: 版权信息

标签

comments honeypot spam antispam no-captcha

下载

1.4 1.5 1.6 1.7 1.1 1.2 1.3 1.8

详情介绍:

Init Void Shield protects WordPress comment forms, the default login/registration/lost-password forms, and popular form plugins with a layered honeypot defense that requires no database tables, no external JavaScript, and no user friction. This plugin is part of the Init Plugin Suite — a collection of minimalist, fast, and developer-focused tools for WordPress. GitHub repository: https://github.com/brokensmile2103/init-void-shield Core honeypot engine (always on for comments):
  1. Dynamic field names — derived from context + site salt (plus an optional custom prefix) so bots cannot hardcode field names.
  2. CSS-clipped honeypots — a text field and a checkbox hidden with rotating CSS techniques (never display:none or visibility:hidden, the two patterns CSS-aware bots specifically look for and skip) that bots fill but humans never see.
  3. Signed time tokens — each form carries a timestamp + HMAC hash verified server-side with hash_equals() to prevent timing attacks. Submissions under the minimum threshold are rejected.
  4. JavaScript + headless-browser verification — a hidden token is injected after a configurable delay (plus a small random jitter, so the exact wait can't be read from the page source and timed around), and the script flags common automation signals (navigator.webdriver, a zero-size browser window) picked up from real Selenium/Puppeteer/Playwright sessions. Static crawlers, instant bots, and unmasked headless browsers all get caught; real users don't.
  5. Non-browser User-Agent detection — rejects submissions whose User-Agent identifies a scripted HTTP client (curl, Python requests, Go, Scrapy, and similar) rather than a real browser, catching bots that skip JavaScript entirely and simply replay the static form fields. On by default; the signature list is filterable.
  6. Block REST API Comments (optional) — rejects comments posted directly through the wp/v2/comments REST endpoint, which the classic form-based layers cannot cover since those requests never carry the honeypot fields or tokens.
  7. Require Same-Site Referer (optional) — rejects a comment submission whose Referer header is missing or points elsewhere, catching bots that post directly to the comment endpoint. Off by default and disclosed as a trade-off, since some privacy-focused browsers strip Referer even on genuine same-site submissions.
Recent updates (1.4–1.6): Key design goals:

安装:

  1. Upload the plugin folder to /wp-content/plugins/
  2. Activate via Plugins → Init Void Shield
  3. Go to Settings → Init Void Shield to review or adjust thresholds, and to opt in to the WordPress core form guards or any form plugin integrations you use

屏幕截图:

  • Form Plugin Integrations & Community/E-commerce Integrations settings
  • Advanced Protection & Statistics settings
  • Init Void Shield admin dashboard widget

常见问题:

Does this work with page builders or custom comment forms?

The plugin hooks into comment_form_after_fields. If your theme uses a custom form, you may need to adjust the hook or manually call the render function.

Can I use this alongside Akismet or other anti-spam plugins?

Yes. Init Void Shield acts as the first line of defense. Other plugins can serve as a secondary layer.

Will this block legitimate users?

No. Logged-in users are bypassed by default on the comment form. Guests only need to wait a few seconds between page load and submit — something every human naturally does.

Can I force verification for logged-in users too?

Yes. Enable Apply to Logged-in Users in the settings if your site has open registration or untrusted members.

Does this protect comments submitted through the REST API?

Not by default. The core layers only run on the classic comment form (preprocess_comment); comments posted directly to wp/v2/comments never carry a honeypot or JS token, so those checks don't apply. The optional "Block REST API Comments" setting is available to close that endpoint entirely if you do not use a headless app or other legitimate REST client for comments.

Are the WordPress login/registration/lost-password guards enabled by default?

No, all three are off by default since they guard authentication itself. Turn them on individually under WordPress Core Forms in the settings, and confirm your own login flow still works afterward. Each covers WordPress's own default form markup at wp-login.php, and the login guard also covers wp_login_form() when used on the front end (e.g. a widget or theme template), unless you set Login Guard Scope to "wp-login.php only" — see the next question. A custom login page/plugin, or Multisite's wp-signup.php registration flow, renders different markup and isn't covered. Each guard can also be force-disabled per request with a dedicated filter (init_plugin_suite_void_shield_skip_login_verification, ..._skip_register_verification, ..._skip_lostpassword_verification), which takes priority over the settings-page toggle.

What is Login Guard Scope?

By default ("Everywhere"), the Login Guard protects both the native wp-login.php form and any front-end wp_login_form() usage (e.g. a custom login page, widget, or modal). If that front-end form lives on a page your cache plugin might serve stale, switch the scope to "wp-login.php only" to leave it entirely unguarded rather than risk a real visitor's login being rejected — the native wp-login.php form stays fully protected either way. This uses the Referer header as a heuristic to tell the two forms apart, which a determined bot could spoof, so it's a deliberate trade-off: only switch away from "Everywhere" if you've hit this specific caching situation.

Are the Contact Form 7 / WPForms / Gravity Forms integrations enabled by default?

No. Each is off by default and only takes effect if the matching plugin is active — the settings page shows a "detected / not detected" status next to each toggle.

Are the WooCommerce / bbPress / BuddyPress integrations enabled by default?

No, same as the other integrations: each is off by default and only takes effect if the matching plugin is active. WooCommerce guards the "My Account" registration form; bbPress guards the New Topic and Reply forms; BuddyPress guards the registration (signup) form. The Multisite signup guard (wp-signup.php) only has an effect on a Multisite install and is also off by default.

Why aren't Ninja Forms or Forminator supported?

Both build their forms client-side and collect submitted data through their own JavaScript field model rather than serializing the whole <form> element, so a honeypot field simply appended to the page would not reliably be sent to the server — it would look like protection without actually doing anything. Both also already ship their own built-in honeypot field. Support may be reconsidered if a reliable hook becomes available.

What is the Maximum Token Age setting?

Each guard issues a signed token good for a limited time window: too fast (below Minimum Submit Time) and too old (above Maximum Token Age) are both rejected. The ceiling exists so a token cannot be captured once and replayed indefinitely; the default of 1 hour is generous enough for a visitor who takes their time filling out a form. Increase it (up to 30 days) if legitimate visitors on your site routinely take longer than that, or if your site uses full-page caching — see the next question.

My site uses aggressive full-page caching and legitimate comments are being rejected as "expired" — what do I do?

On a cached page, the time token baked into the HTML reflects the moment the page was cached, not the moment a real visitor loaded it. If your cache lifetime is long, that gap can exceed the Maximum Token Age. Two options, either works on its own: raise Maximum Token Age to comfortably cover your cache lifetime, or enable Lazy Fetch under Advanced Protection, which refreshes the token client-side right after the page truly loads, so timing is always measured from the real visit regardless of cache age.

What does Lazy Fetch do, and is it safe?

When enabled, a small same-origin JavaScript request (no jQuery, no external service) fetches a fresh, correctly signed time token right after the page loads, and overwrites the one baked in at render time. It's stateless — the endpoint only recomputes the same signed hash the page would already have shown, and is only registered at all while Lazy Fetch is enabled. If the request fails, or JavaScript is unavailable, the original baked-in token is used as-is, exactly like before Lazy Fetch existed — so enabling it can only help, never introduce a new failure mode. Off by default; applies to every guarded form, not just comments.

I updated from an older version and my Minimum Submit Time / JS Token Delay no longer behaves the way I remembered — why?

Versions before 1.4 had a bug where these two settings were saved correctly but never actually read back during verification, so the plugin always silently enforced the defaults (3 seconds / 1000ms) no matter what was configured. 1.4 fixes this, so a custom value you set earlier may now be enforced for the first time. This is a bug fix, not a new restriction — just double-check both values on the settings page after updating.

What does "Require Real User Interaction" do?

When enabled, a submission is only accepted if the browser recorded at least one real mouse, keyboard, touch, or scroll event before the JS token fires — and that event only counts once a short minimum delay of its own has passed, so a bot can't satisfy it by firing one synthetic event the instant the page loads. It targets bots that wait out the JavaScript Token Delay instead of a real page visit. It's off by default and works best paired with a JS delay of at least 1-2 seconds.

What does "Block Non-Browser User Agents" do, and is it safe to leave on?

It rejects any submission whose User-Agent header identifies a scripted HTTP client — curl, Python's requests library, Go's default client, Scrapy, PostmanRuntime, and similar — rather than a real browser. It's on by default and is one of the safest checks in the plugin: every real browser, including all the major ones and their mobile variants, sends its own distinct browser User-Agent, never one of these library defaults. It specifically catches a bot that never runs JavaScript at all — one that parses the static HTML, avoids the honeypot fields, and replays the baked-in time/hash token — which the honeypot and JS layers can't see on their own. If you run your own legitimate script against your comment form (e.g. an internal test tool), either give it a normal browser User-Agent or use the init_plugin_suite_void_shield_skip_verification filter for that request.

What does "Require Same-Site Referer" do?

When enabled, a comment submission is rejected if its Referer header is missing or points to a domain other than your own — this catches a bot that posts directly to the comment endpoint without ever actually loading the page. It's off by default and disclosed as a trade-off, same as Login Guard Scope's Referer heuristic: some privacy-focused browsers and extensions strip the Referer header even on a genuine same-site submission, and this check cannot tell that apart from a bot. Only enable it after confirming it doesn't affect real commenters on your site, and treat it as one more layer on top of the others rather than a replacement for them. A init_plugin_suite_void_shield_referer_exempt filter is available if you need to exempt specific requests (e.g. a proxy or caching setup that legitimately strips Referer).

Can I change the honeypot field names?

Yes. Set a Custom Field Prefix under Advanced Protection. Field names are still dynamically derived per context and site salt on top of that prefix.

Does the headless-browser detection call any external service?

No. It only reads navigator.webdriver and the browser window size on the visitor's own device — no external requests, no tracking.

What does the statistics feature store?

Only aggregate counters (a total, a breakdown by channel, a breakdown by block reason, and a last-blocked timestamp) in one non-autoloaded option. No per-submission logs, IP addresses, or personal data are recorded. It can be turned off or reset from the settings page at any time.

Is the Dashboard widget on by default?

No. Enable Show Dashboard Widget under Statistics. It's only visible to users who can manage options, and only shows the same aggregate counters as the settings page (no per-submission data).

I see a JavaScript syntax error in the browser console near "lazyFetchEnabled", and every comment gets rejected — what's happening?

This was a bug fixed in 1.8: some environments (an HTML minifier, a multilingual plugin, a security/output-filtering plugin, or WordPress's own convert_chars()) rewrite a bare & in page output into &, which is safe for ordinary HTML text but breaks the literal JavaScript inside a <script> tag, since browsers never decode entities there. If you're on 1.8 or later and still see this, please report it along with your active plugins/theme so the specific source can be identified.

Can developers customize the behavior?

Yes. See the Filters section below for the full list, or the documentation on GitHub for more detail.

更新日志:

1.8 – September 8, 2026 1.7 – September 1, 2026 1.6 – August 30, 2026 1.5 – August 30, 2026 1.4 – August 30, 2026 1.3 – August 24, 2026 1.2 – August 23, 2026 1.1 – August 13, 2026 1.0 – July 30, 2026