Skip to main contentSkip to footer
Plugin Guides

Gravity Forms Spam Protection Without a Captcha

Patrick Schlesinger
ReportedIP Hive plugin guide banner: Gravity Forms spam protection without a captcha

Gravity Forms spam protection without a captcha means the site checks that a real browser rendered and submitted the form, instead of asking the visitor to prove it. ReportedIP Hive does exactly that for Gravity Forms: a bot’s submission is refused as a validation error above the form, no entry is written, and a genuine sender never sees a puzzle, an image or an extra step.

The Gravity Forms adapter is part of the Business plan and switches on with one toggle on the Protection page under Form Protection. It arrived with Hive 2.1.63 and is tested against Gravity Forms 3.1.

Why a captcha is the wrong tool for a contact form

A captcha asks the wrong person to do the work. The sender, who wants to reach you, has to read distorted letters or click on traffic lights; the script that floods the form was never going to solve it and simply moves on to a site with a weaker one. Every failed attempt costs you a message, and you never learn how many gave up.

Bots fall into two groups, and a form has to handle both. The first fills in every field it finds, including the one it should skip. The second never loads the page at all: it posts straight at the endpoint with a payload copied from one real submission. Gravity Forms ships its own honeypot field for the first group. The second walks past a honeypot, because it never renders the markup that carries it.

How the execution proof judges a Gravity Forms submission

Hive plants one invisible anchor field in every Gravity Forms form on the page, excluded from the tab order and from screen readers. A small script then adds a second field whose name is different on every installation, so a payload recorded on one site fits no other. On submission the server reads both fields back and sorts the request into one of four verdicts:

VerdictWhat the submission carriedWhat happens
provedAnchor empty, proof field presentA browser rendered the form and ran its script. The entry is saved.
trippedThe anchor field, filled inRefused. A filled invisible field is automation with no innocent explanation, and the address moves up the block ladder.
failedAnchor empty, proof field missing, the site knows it renders the fieldRefused. The page was fetched, the script never ran.
absentNeither field presentLenient. Hive has not yet seen itself render the field on this site, so nothing is judged.

Nothing request-specific reaches the HTML. The anchor is the same on every page load, the randomised name lives in the script, so a page cache can keep serving the form for as long as it likes without a single visitor being locked out.

Gravity Forms submits its forms itself

Most form plugins submit through the browser’s normal submit event, which is where Hive’s script fills the proof field. Gravity Forms does not: it collects and sends the form on its own and fires no submit event doing so. It does publish a JavaScript filter for exactly this moment, gform/submission/pre_submission, the same one its own invisible captcha uses. Hive hooks that filter, fills the proof field, and hands the form back.

On the server the anchor goes in through gform_form_tag, so it sits inside the form element without searching the markup for a closing tag, and the verdict is delivered on gform_validation, the hook Gravity Forms runs on every submission before it writes an entry.

Multi-page forms are judged once, on the last page

A form with several pages sends each page as a request of its own. Only the final page is a submission, so only that one is judged. Judging every step would spend a computed answer and a community lookup for nothing. Forms sent in the background, the AJAX mode most sites use, are covered the same way as a form sent with a page reload, and the refusal is shown above the form on both paths.

A form that arrives late is taken in again

A Gravity Forms form rendered a second time, after a failed validation or inside a popup, arrives after the script’s first pass. Hive listens for the plugin’s own render event and takes the form in again: it reads the challenge, restarts the clock and binds the submission filter. Before 2.1.63 such a form found no computed answer waiting and was refused as unproven; that is fixed.

Why a refused submission is a validation error and not a spam-folder entry

Gravity Forms offers a spam folder, and the adapter could have filed refused submissions there. It does not, on purpose. An entry in the spam folder is a message the sender was thanked for and the operator never reads. If the verdict was wrong, the person who wrote to you believes their message arrived and waits for an answer that never comes.

A refusal from Hive is a form-level validation error instead, the same mechanism Gravity Forms uses for its own “at least one field must be filled out”. The sender sees the message above the form, can read why, and can try again. No entry is written, no notification goes out, and no confirmation page is shown. This plugin never loses a message without at least telling the sender so.

What a bot sees and what a visitor sees

Genuine visitorScript posting at the endpointBot filling every field
Loads the pageYesNoYes
Runs the scriptYesNoUsually not
Proof fieldPresentMissingMissing or wrong
Anchor fieldEmptyEmpty or missingFilled
Extra step for the humanNone
ResultEntry savedRefused above the formRefused, address counted

What the check cannot do is tell a person from a botnet driving a real browser. It tells a browser from a script. For the address behind the browser, Hive runs a second, independent check: the community threat check refuses a submission from an address the site would refuse a sign-in to, at the protection level the sign-in page enforces, and the sender is told why. That check needs Community Network mode; the execution proof works in Local Shield mode as well, with nothing leaving the site.

Submissions made through the Gravity Forms API are never judged

An import, a Zapier feed or a REST call through the Gravity Forms API carries no anchor and no proof field, and without a rule for that, every one of them would read as a client that failed the check. Hive asks the validation hook whether the submission came from a browser and stands aside for everything else. Since Gravity Forms 2.6.4 the hook says so itself; on an older plugin Hive asks the way the plugin’s own honeypot asks.

Switching it on in four steps

  1. Update to Hive 2.1.63 or later on a Business plan. On a lower plan the Gravity Forms switch stays visible and locked, with the plan it needs written next to it.
  2. Turn on the Gravity Forms switch on the Protection page under Form Protection. Switching it on clears the common page caches, and for 24 hours a submission that never carried the proof is still accepted, so a page cached without the field cannot lock anybody out. The reportedip_hive_form_adapters_grace filter buys more room on a site whose cache outlives a day.
  3. Run the self-test under Tools → Diagnostics. The card lists what is switched on and then runs three passes with the browser you are sitting in front of: like a visitor, like the same visitor twice, and like a bot. No real form is submitted, no mail goes out and no entry is stored. An invisible protection is otherwise hard to tell apart from no protection at all.
  4. Optionally start in report-only mode, which logs every verdict and refuses nothing. A week of logs shows what would have been refused before anything is.

The computation check, included from Professional and therefore on Business, closes the one shortcut the plain proof field leaves open: reading the field name out of the page and posting it back. The browser works out a small sum in the background, each answer is accepted once, and the sender still notices nothing. It needs HTTPS; without it the plain proof field keeps deciding.

Which form plugins get the same protection

FormPlanTested against
Comment, sign-up and lost-password formsFreeWordPress core, WooCommerce, Multisite
Your own forms, through the form APIFreeThree calls: field, check, passes
Contact Form 7Every planThe version published on wordpress.org
Gravity FormsBusiness3.1, including multi-page and background forms
Formidable Forms and Formidable Forms PROBusiness6.35
Elementor FormsBusinessElementor PRO 3.34, the form widget exists only there
Ultimate MemberBusiness2.13, sign-in, sign-up and password forms

Each plugin has its own switch. The whole layer, the master switch, a second switch that leaves sign-up and password reset out, and report-only mode sit together on the Protection page. REPORTEDIP_HIVE_DISABLE_FORM_PROOF in wp-config.php switches the layer off for the case where a visitor cannot submit and you need the site working before you debug.

Frequently asked

Does Gravity Forms still need a captcha with Hive switched on?

Not against scripts and bots. The execution proof catches a submission that never rendered the form and a bot that fills the invisible field, and the community threat check refuses an address the network already knows. A captcha adds nothing to that except a step the sender has to take. What no field can do is tell a person from a botnet driving a real browser, and a captcha cannot do that either.

Does it work next to Akismet or the Gravity Forms honeypot?

Yes. Hive judges the submission on the validation hook, before an entry exists. A refused submission never reaches the entries list, the spam folder or any other anti-spam plugin. Everything that passes goes on to the checks you already run.

What happens to a visitor with JavaScript switched off?

On the form plugins a submission without the proof is refused with a message that says why, because on a contact form there is no moderation queue to fall back on. On the comment form the same case only costs a moderation step. A site with many such visitors can run the layer in report-only mode, or leave the Gravity Forms switch off and keep the free forms covered.

Does the check slow the form down or break page caching?

No. The anchor is identical on every page load and nothing request-specific reaches the HTML, so a cached page stays valid. The script fills one field at submission time and measures how long the form was on screen; the starting point comes from the browser, never from the markup, so a cached page cannot carry a stale one.

Is it GDPR compliant?

The proof collects nothing about the visitor beyond whether two hidden fields were present on submission and how many seconds the form was on screen. No fingerprinting, no third-party request, no image served from another domain. In Local Shield mode nothing leaves the site at all. The WordPress plugin documentation carries the full data-handling summary.

Related reading

See the WordPress plugin documentation for the full settings reference and the plan comparison for what Business includes. Explore ReportedIP Hive →

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.
You need to agree with the terms to proceed