Title: FormGhost
Author: byabdalla
Published: <strong>September 17, 2026</strong>
Last modified: September 17, 2026

---

Search plugins

![](https://ps.w.org/formghost/assets/banner-772x250.png?rev=3701068)

![](https://ps.w.org/formghost/assets/icon-256x256.png?rev=3701068)

# FormGhost

 By [byabdalla](https://profiles.wordpress.org/byabdalla/)

[Download](https://downloads.wordpress.org/plugin/formghost.1.2.4.zip)

 * [Details](https://wordpress.org/plugins/formghost/#description)
 * [Reviews](https://wordpress.org/plugins/formghost/#reviews)
 *  [Installation](https://wordpress.org/plugins/formghost/#installation)
 * [Development](https://wordpress.org/plugins/formghost/#developers)

 [Support](https://wordpress.org/support/plugin/formghost/)

## Description

**The spam never happened.** FormGhost is a privacy-first WordPress antispam plugin
that makes spam quietly disappear: bots are shown a fake success page and walk away
believing they got through, while you never receive a thing. No CAPTCHA is ever 
shown, no data leaves your server, and no personally identifiable information is
kept on disk. Spam goes into the Vault. Real users never see anything.

**Every feature is free. There is no Pro version, no license key, no upsell.**

#### Why FormGhost

 * No CAPTCHAs. No “select all the buses.” No “I’m not a robot” checkbox.
 * No cloud dependency — the spam detection itself makes no external HTTP calls.
   The only optional exceptions (CAPTCHA verification, MX lookup) are off by default
   and documented under External services.
 * GDPR / DSGVO friendly. IP addresses are hashed with a per-site secret before 
   storage. Form payloads are encrypted (AES-256-GCM) in the vault.
 * Ghost Response: bots see a fake success message and walk away thinking the submission
   worked. You never get the email.
 * Blocked something legitimate? Open it in the Vault and forward it to the inbox
   it was headed to with one click.

#### How it works

Every submission is graded by up to nine independent layers. Each layer adds a small
score. When the total crosses the configured threshold, FormGhost takes action —
usually a silent Ghost Response, so the bot never learns it was blocked.

 1.  **Honeypot** — Daily-rotated, site-suffixed hidden fields. Different on every 
     FormGhost site; resistant to “fill every field” bots.
 2.  **Timing** — Encrypted submission timestamp. Submissions that arrive too fast (
     or with a replayed token) fail this layer.
 3.  **Proof-of-Work** — Lightweight browser challenge solved by a WebWorker. Stops
     curl / wget / scripted submissions cold.
 4.  **Behavioral fingerprint** — Mouse curvature, keystroke variance, scroll, focus
     and touch signals computed entirely in the browser. Only the resulting score is
     transmitted.
 5.  **Rate limiting** — Per-IP and per-form submission caps with sliding windows and
     CIDR-aware whitelisting.
 6.  **Disposable email detection** — Curated disposable-domain blocklist (extensible
     with your own block/allow lists), optional MX heuristic.
 7.  **Content patterns** — Casino / SEO / pharma phrase detection with a self-learning
     twist.
 8.  **WordPress hardening** — Disable XML-RPC, harden the REST users endpoint, generic
     login errors, optional Application Passwords lockdown.
 9.  **Optional CAPTCHA** — Turnstile / hCaptcha / ALTCHA on the core WordPress forms
     you choose (comments, login, registration, password reset) if you want a visible
     challenge as a last line of defence. Off by default.

#### Form plugin compatibility

Built-in adapters for:

 * WordPress core comments, login, registration, password-reset
 * Contact Form 7
 * WPForms
 * Gravity Forms
 * Elementor Pro Forms
 * WooCommerce checkout & registration
 * Fluent Forms
 * Ninja Forms
 * Formidable Forms
 * Forminator
 * HTML Forms
 * Jetpack Forms
 * Bricks Builder forms
 * Kadence Blocks forms
 * Divi contact forms
 * BuddyPress signup & activity
 * bbPress topics & replies

Custom forms POSTing to `wp-admin/admin-post.php` or `wp-admin/admin-ajax.php` are
picked up automatically by the generic adapter.

#### The Vault

Blocked submissions are stored encrypted for 30 days (configurable). Review them
in the admin: see what was blocked, which page it was submitted from, and which 
inbox the notification was headed to. Mark false positives as legitimate and forward
them by email with one click — the sender’s address becomes the Reply-To, so answering
in your mail client reaches the person who filled the form. Passed (legitimate) 
submissions are logged too, so you can audit both sides of every decision.

#### Self-learning

When you mark a Vault entry as “spam” the engine extracts the email domain / content
phrase signatures and stores them in a learned-rules table with a score modifier.
Future submissions matching those signatures get extra points, automatically. Auto-
confirmed rules from repeat offenders are added too. Decay over time keeps the rule
set fresh. Review, re-weight, deactivate or delete every learned rule from the Learned
Rules screen.

#### Privacy

 * The nine detection layers, the Vault and the self-learning system run entirely
   on your server. Two optional, off-by-default features talk to the outside: CAPTCHA
   verification (Cloudflare Turnstile / hCaptcha) and the DNS MX check — see “External
   services” below.
 * IPs are stored only as `sha256(site_secret + "|" + ip)` and cannot be recovered.
 * Vault payloads are encrypted at rest with AES-256-GCM (authenticated encryption).
 * Uninstalling the plugin removes every option, every table and every cron event.
   Nothing is left behind.

### External services

FormGhost’s spam detection runs entirely on your own server. Two optional features,
both **off by default**, connect to third parties. Nothing is sent unless you enable
them in the settings.

**Cloudflare Turnstile** (Layer 9, optional CAPTCHA provider)
 When you enable the
CAPTCHA layer with Turnstile for a form, the plugin renders the widget container
on that form (you add Cloudflare’s widget script `https://challenges.cloudflare.
com/turnstile/v0/api.js` to your site yourself — the plugin does not load any vendor
script), and on every submission of that form the plugin sends the widget’s response
token, your Turnstile secret key and the visitor’s IP address to `https://challenges.
cloudflare.com/turnstile/v0/siteverify` to verify the challenge. Terms: https://
www.cloudflare.com/terms/ — Privacy: https://www.cloudflare.com/privacypolicy/

**hCaptcha** (Layer 9, optional CAPTCHA provider)
 When you enable the CAPTCHA layer
with hCaptcha for a form, the plugin renders the widget container on that form (
you add hCaptcha’s widget script `https://js.hcaptcha.com/1/api.js` to your site
yourself — the plugin does not load any vendor script), and on every submission 
of that form the plugin sends the widget’s response token, your hCaptcha secret 
key and the visitor’s IP address to `https://api.hcaptcha.com/siteverify` to verify
the challenge. Terms: https://www.hcaptcha.com/terms — Privacy: https://www.hcaptcha.
com/privacy

**ALTCHA** (Layer 9, optional CAPTCHA provider) is self-hosted: the challenge endpoint
and the verification run on your server (`admin-ajax.php?action=formghost_altcha_challenge`);
no data is sent anywhere. You add the ALTCHA widget script to your site yourself.

**DNS MX lookup** (Layer 6, optional “Check MX records” setting)
 When enabled, 
the plugin asks your server’s DNS resolver for the MX records of the submitted email
address’s domain (PHP `getmxrr`). This is a standard DNS query from your server,
not a request to a third-party API; the email address itself is not transmitted,
only its domain.

### Privacy

FormGhost is designed for privacy-conscious operators.

**Data stored on your server.**

 * `{prefix}formghost_vault` — encrypted form payloads of blocked / passed submissions
   plus `sha256(IP + site_secret)` and `sha256(User-Agent + site_secret)` hashes.
   AES-256-GCM authenticated encryption keyed off the per-site secret. Configurable
   retention (default 30 days). Removed on uninstall.
 * `{prefix}formghost_learned_rules` — score modifiers learned from admin review
   and auto-confirmation. A rule may hold the sender email address of a submission
   you reviewed, or an IP stored only as `sha256(IP + site_secret)`. Rules decay
   when stale and can be deleted from the Learned Rules screen. Removed on uninstall.
 * `{prefix}formghost_log` — block / pass counters per layer per form type for the
   dashboard. No PII. Removed on uninstall.
 * `formghost_site_secret` (option) — 64-char random secret used for IP / UA hashing,
   payload encryption and CSS class derivation. Removed on uninstall.

**Data sent off your server.** None by default. Only the optional services listed
under “External services” send anything, and only after you enable them.

**Cookies.** FormGhost does not set cookies.

For full source, audit, and integration docs, see https://byabdalla.com/lab/formghost.

## Screenshots

[⌊The Dashboard — blocked and passed counts, layer breakdown, recent activity.⌉⌊
The Dashboard — blocked and passed counts, layer breakdown, recent activity.⌉[

The Dashboard — blocked and passed counts, layer breakdown, recent activity.

[⌊The Vault — review blocked submissions; see the source page and recipient; forward
with one click.⌉⌊The Vault — review blocked submissions; see the source page and
recipient; forward with one click.⌉[

The Vault — review blocked submissions; see the source page and recipient; forward
with one click.

[⌊Settings — choose exactly where FormGhost runs; every layer is tunable.⌉⌊Settings—
choose exactly where FormGhost runs; every layer is tunable.⌉[

Settings — choose exactly where FormGhost runs; every layer is tunable.

[⌊Learned Rules — see what the engine learned from your reviews.⌉⌊Learned Rules —
see what the engine learned from your reviews.⌉[

Learned Rules — see what the engine learned from your reviews.

[⌊The wp-admin dashboard widget — key numbers right after login.⌉⌊The wp-admin dashboard
widget — key numbers right after login.⌉[

The wp-admin dashboard widget — key numbers right after login.

## Installation

 1. Upload the `formghost` folder to `wp-content/plugins/` (or install through the 
    Plugins screen).
 2. Activate FormGhost on the Plugins screen.
 3. Run the one-time wizard that appears on activation — toggle the surfaces to protect
    and pick a sensitivity profile; FormGhost presets every layer.
 4. Done. Real users keep submitting; bots stop arriving.

## FAQ

### Is FormGhost really completely free?

Yes. All nine layers, the Vault, the self-learning system, Ghost Response — everything
ships in the free plugin. There is no Pro tier and no license key.

### Will it break my real forms?

No. FormGhost is invisible — no CAPTCHA, no extra fields visible to humans, no JavaScript
prompts. The honeypot fields are hidden via multiple CSS techniques and `aria-hidden`.
The timing token and proof-of-work fields are injected by JavaScript with no UI 
footprint.

### Does it work without JavaScript?

The honeypot and email-content layers work without JavaScript. The timing and proof-
of-work layers require JavaScript on the visitor’s side; you can configure FormGhost
to allow no-JS submissions (less strict) or to block them as suspect (stricter).

### Does it send data to your servers?

No — FormGhost has no servers of its own and its spam detection never leaves your
site. The only outbound calls the plugin can make are the optional, off-by-default
Turnstile / hCaptcha token verification and the DNS MX lookup, both described under“
External services” below.

### How does the wizard configure my site?

Choose which surfaces to protect (comments, login, registration, contact forms, 
WooCommerce, password reset) and a sensitivity profile — Low, Medium or High. FormGhost
applies a curated recipe of timing thresholds, proof-of-work difficulty and pattern
aggressiveness. You can fine-tune everything afterwards in Settings, and re-run 
the wizard any time.

### I marked a legitimate submission as blocked. What now?

Open the Vault, find the entry, click “Mark legitimate” — and click “Send” to forward
it to the inbox it was originally headed to. The Learning system learns from your
correction and lowers the weight of any rule that contributed to the false positive.

### Can I see what each layer did to a submission?

Yes. The Vault detail view shows the score, the triggering layer, the reason code,
the page the form was submitted from, and the notification recipient for every stored
submission.

### Does it work with caching plugins?

Yes. The honeypot CSS is inline, the timing token and PoW challenge are fetched 
at submission time via a cache-bypassed AJAX endpoint, and the Behavioral layer’s
nonce is also live-issued. Heavy page caching does not weaken FormGhost.

### Is it compatible with WP Rocket / W3 Total Cache / Cloudflare?

Yes. None of the runtime fields are baked into the cached HTML. The plugin sends`
nocache_headers()` on its own AJAX endpoint.

### Where are blocked submissions stored?

In a `{prefix}formghost_vault` table you control, encrypted with AES-256-GCM against
a per-site secret stored in `formghost_site_secret`. Default retention is 30 days;
configurable; uninstall removes the table entirely.

### I run a forum / membership / e-commerce site — what do you recommend?

Run the wizard once and enable the registration / WooCommerce scopes that match 
your attack surface, with the Medium sensitivity profile. Layers 4 (Behavioral),
5 (Rate limit) and 6 (Email) add the most uplift against modern bots and are on 
by default.

## Reviews

There are no reviews for this plugin.

## Contributors & Developers

“FormGhost” is open source software. The following people have contributed to this
plugin.

Contributors

 *   [ byabdalla ](https://profiles.wordpress.org/byabdalla/)

[Translate “FormGhost” into your language.](https://translate.wordpress.org/projects/wp-plugins/formghost)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/formghost/), check 
out the [SVN repository](https://plugins.svn.wordpress.org/formghost/), or subscribe
to the [development log](https://plugins.trac.wordpress.org/log/formghost/) by [RSS](https://plugins.trac.wordpress.org/log/formghost/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

#### 1.2.4

 * WordPress.org review: the release package no longer contains the directory artwork
   folder or other non-runtime files.
 * Elementor Pro preflight now respects the master switch, the contact-form scope
   toggle, the IP whitelist and the `formghost/skip_form` filter, so a disabled 
   FormGhost never intercepts an Elementor submission.
 * Layer 9 CAPTCHA can now actually be switched on: new per-form toggles (comments,
   login, registration, password reset) and the widget container is printed on those
   core forms automatically.
 * “Store passed submissions” now controls whether passed submissions are stored
   in the Vault (they are still counted when off).
 * Programmatic settings saves (setup wizard) no longer reset developer-managed 
   array settings.
 * Uninstall also removes the per-user “items per page” screen options.
 * Honeypot CSS is delivered once: the stylesheet WordPress prints in the page head
   now carries a marker, and the front-end script only injects its own copy when
   that stylesheet is missing.
 * Documentation: FAQ and Privacy sections corrected (optional external calls, what
   learned rules can contain); stale development notes removed from code comments.

#### 1.2.3

 * WordPress.org review: the generic interceptor now classifies admin-ajax.php /
   admin-post.php requests via core’s own signals (`wp_doing_ajax()`, `$pagenow`)
   instead of matching the request URI, so non-standard wp-admin locations work.
 * WordPress.org review: settings tab selection now travels inside the Settings 
   API’s nonce-verified option input; the Contact Form 7 adapter no longer falls
   back to reading the raw request; the Elementor recipient resolver receives the
   validated page ID from the adapter instead of reading the request itself.
 * WordPress.org review: POST field names in the Kadence and Divi adapters are sanitized
   before use; nested array values in the generic interceptor are recursively sanitized
   before scoring.
 * Hardened Vault and Rules admin write paths: explicit capability check before 
   any action, nonce checks untangled into standalone conditions, and row actions
   validated against a closed list. Rules row-action nonces are now bound to the
   individual rule ID.
 * Token issuance (timing token, proof-of-work challenge, behavior nonce, ALTCHA
   challenge) is now fully stateless — HMAC-signed with the expiry embedded — so
   anonymous bootstrap requests write nothing to the database; single-use markers
   are written only when a token is actually consumed by a submission.
 * When “behind reverse proxy” mode is enabled, the client IP is now taken from 
   the right-most public X-Forwarded-For hop (the one vouched for by the trusted
   proxy) instead of the left-most, which a client can spoof.
 * Ghost Response success messages are sanitized at the source and HTML-escaped 
   in every per-plugin JSON envelope.
 * The version constant is a literal instead of re-parsing the plugin header on 
   every request.

#### 1.2.2

 * WordPress.org review: removed leftover cleanup code from the pre-1.1 licensing
   system and the retired Ghost Network source; the plugin contains no gating code
   of any kind — every feature is free.
 * Inline `<style>` blocks (dashboard widget, honeypot) moved to enqueued stylesheets.
 * Translations now come from translate.wordpress.org language packs; the bundled
   compiled files and the `load_plugin_textdomain()` call were removed.
 * readme: full “External services” disclosure for the optional Turnstile / hCaptcha
   verification calls and the optional DNS MX lookup.
 * Improved: marking a Vault entry as spam is now decisive — the sender’s exact 
   address (+50) and hashed IP (+30) are learned alongside the content signals, 
   so the next message from that sender is ghosted; marking as legitimate (-50 on
   the address) guarantees a wrongly held sender passes. Learned rules now also 
   apply to submissions without free text.

#### 1.2.1

 * Fixed: Contact Form 7 submissions arrive through the REST API, where the timing,
   proof-of-work and behavior layers and the bot preflight were skipped — only the
   honeypot and content patterns judged them. They now run for CF7 exactly as for
   a page POST. New filter `formghost/engine/rest_browser_form_types` for other 
   JS-driven REST forms.
 * New: cross-layer check — a submission that passed the timing or proof-of-work
   check but carries no behavior data (which the tracker injects into every form)
   is scored as a bot (`missing_after_js`).
 * New: identity-churn detection — one email address submitting under changing names,
   or one IP sending as many different people, within seven days. The Vault stores
   keyed hashes only (never the address). Toggle under Layer 5.
 * New: the Learning layer now tracks the full sender address as a rule type (“Email
   address”), so a mailbox reused by a bot escalates as a repeat offender even on
   gmail.com / mail.ru.
 * Improved: content patterns learn lead-generation, “website traffic”, directory-
   listing, newsletter-bombing and advance-fee scam vocabulary; new structural signals—
   unsubscribe boilerplate, a third-party link carrying this site’s own domain, “
   Hello Owner” greetings, repeated links, emoji bait, throwaway hosting (vercel.
   app, netlify.app, workers.dev, …) and 19 more URL shorteners, matched by host.

#### 1.2.0

 * New: adapters for six more form plugins — Forminator, HTML Forms, Jetpack Forms,
   Bricks Builder, Kadence Blocks, and Divi contact forms.
 * New: complete Arabic translation, with right-to-left admin support.

#### 1.1.0

 * Everything is free: all nine layers, self-learning, Learned Rules screen and 
   Ghost Response now ship free of charge. The former activation screen was removed.
 * New: “Passed” card on the dashboard — see the submissions that were NOT blocked
   and click through to review them.
 * New: FormGhost widget on the main wp-admin dashboard with blocked/passed counts
   and quick links.
 * New: dashboard stat cards link into the filtered Vault views.
 * Improved: “Blocked today” now follows the site’s timezone instead of UTC.
 * Improved: ghost-response counting is exact — it no longer under-counts when ghost
   logging is off or entries are reviewed/purged.
 * Improved: email domains in the Vault are shown in full, and the search box matches
   partial domains.
 * Improved: the IP whitelist now honours CIDR ranges in every layer, including 
   the engine’s early skip.
 * Improved: Vault filters cover every supported form plugin (Fluent, Ninja, Formidable,
   BuddyPress, bbPress, custom forms, password reset).
 * Fixed: default settings are now merged on front-end requests too, so a partially
   saved settings option can never silently disable a layer.
 * Fixed: the “Protect contact-form plugins” toggle now also covers custom forms
   caught by the generic interceptor.

#### 1.0.0

 * Initial public release.

## Meta

 *  Version **1.2.4**
 *  Last updated **1 day ago**
 *  Active installations **Fewer than 10**
 *  WordPress version ** 6.0 or higher **
 *  Tested up to **7.1.1**
 *  PHP version ** 7.4 or higher **
 * Tags
 * [antispam](https://wordpress.org/plugins/tags/antispam/)[captcha alternative](https://wordpress.org/plugins/tags/captcha-alternative/)
   [GDPR](https://wordpress.org/plugins/tags/gdpr/)[honeypot](https://wordpress.org/plugins/tags/honeypot/)
   [spam](https://wordpress.org/plugins/tags/spam/)
 *  [Advanced View](https://wordpress.org/plugins/formghost/advanced/)

## Ratings

No reviews have been submitted yet.

[Your review](https://wordpress.org/support/plugin/formghost/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/formghost/reviews/)

## Contributors

 *   [ byabdalla ](https://profiles.wordpress.org/byabdalla/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/formghost/)