About this plugin
Most captchas stop spam by making your visitors do the work. Tick the box, then pick out every traffic light anyway. Free Captcha Protection hands that job to the visitor’s browser, so people just fill in your form and press send.
As soon as someone starts using a protected form, their browser works through a small proof-of-work calculation in the background. On most devices it takes about a second, usually while the person is still typing. Bots that post straight to your forms never run it, so they arrive without a valid answer and get turned away.
All of it happens on your own server. The plugin never talks to Google, Cloudflare or anyone else, and it sets no cookies. There’s no account to create and no API key to paste in.
It’s free.
We made it for the client sites we build and look after at MJ Studios. Now you can use it on yours.
Replaces Google reCAPTCHA, Cloudflare Turnstile and hCaptcha
Google reCAPTCHA, Cloudflare Turnstile, hCaptcha and Friendly Captcha all ask you for an account and a site key, and each loads its script from the provider’s servers. This plugin does the same job from your own server. It’s free, and there’s nothing to sign up for.
Switch the old captcha off, activate this one, and the forms below are protected straight away. You don’t have to edit a single form.
Works with the forms you already have
The plugin sees which form plugins are active and protects their forms by itself. Each one has a switch under Captcha Protection > Settings, so you can leave any of them out.
- WordPress login, registration, lost password and comments
- WooCommerce lost password, plus login, registration and the classic checkout once you switch them on
- Fluent Forms (its conversational forms aren’t covered yet)
- Contact Form 7
- WPForms
- Gravity Forms
- Ninja Forms
- Formidable Forms
- Forminator
- WS Form
- Everest Forms
- Elementor Pro forms
- Kadence Blocks forms
- MetForm
- HappyForms
- Jetpack Forms
- Bricks forms
- Any other form, using the [mjscp_captcha] shortcode and mjscp_verify()
Forms built with Divi, Beaver Builder, Otter Blocks, Spectra and Brizy are protected as well, but we call those experimental for now because they haven’t run on many real sites yet. If one of them gives you trouble, switch it off in Settings and tell us in the support forum.
Protection is on with sensible defaults from the moment you activate it.
What your visitors notice
Ideally, nothing.
- Nothing loads until someone interacts with a form, so your page speed stays where it was.
- The widget stays hidden. If a submission is turned away, the message shows up where the form puts its other errors.
- If someone presses submit before the answer is ready, the form waits a moment and then sends itself.
- Each answer works once. The widget then fetches a fresh challenge, so AJAX forms can be sent again without a page reload.
- Forms that send without reloading the page work, and so do forms in popups and pages with more than one form.
- The work runs in Web Workers using the browser’s built-in crypto, with a pure JavaScript fallback for older browsers and sites on plain HTTP.
- Page caching is fine, because challenges are fetched fresh when a form is used.
When the check can’t run
Now and then the check can’t finish in someone’s browser. A privacy extension might block the script, or a strict network might block the request for a challenge. Rather than turn a real person away, the plugin sends the form anyway and leans on its other checks: the honeypot, the time spent on the form and the spam score.
These submissions show up as “Let through” on the Activity screen. Each IP address gets three an hour and the whole site gets 50, so bots can’t use this as a way around the proof of work. A fault in the plugin is handled the same way.
If the check hits an error on your server, the message still goes through and the error lands in the log.
Plugins that handle their own spam
Contact Form 7, Formidable Forms, Gravity Forms and Jetpack Forms each deal with spam in their own way. For these four, a failed check hands the submission to that plugin as spam by default, and the plugin treats it like any other spam. If you’d rather turn failed submissions away with an error message, pick Reject for that plugin in Settings.
Extra checks behind the scenes
- A hidden honeypot field that only bots fill in
- A minimum time on the form, because nobody writes a message in half a second
- A spam score that counts links in messages and notices requests with missing browser headers
- Automatic IP blocking after repeated failures (by default, 5 failures in an hour earns a 24 hour block)
- An allowlist for single IPs and IPv4 ranges
- Support for Cloudflare and other proxies, so blocks land on the real visitor IP
You can’t lock yourself out. Login forms ignore IP blocks, and an IP an administrator has used is never blocked automatically.
See what it stopped
The Overview screen shows how your forms held up over the last 7, 14 or 30 days. You get totals compared with the period before, a daily chart you can hover for each day’s numbers, the block rate, the IPs that failed most and a breakdown by form and by reason.
The Activity screen lists every check, newest first, and you can filter it by result, form or IP. Blocked IPs have their own screen, where you can block an address for a day, a week, a month or for good, and lift a block again.
The admin screens are part of the plugin and load nothing from outside your site, so they open quickly. They work with JavaScript switched off too.
Privacy
The plugin was designed with privacy laws such as the GDPR in mind.
- It sets no cookies and stores nothing in the visitor’s browser.
- It makes no requests to outside services, so visitor data stays on your server.
- The verification log keeps the IP address, browser user agent, form name, form ID and result for 30 days by default. You can shorten that to one day or switch the log off.
- It remembers the last 20 IP addresses your administrators used, only so it never blocks them.
- It adds suggested wording for your privacy policy under Settings > Privacy.
- Deleting the plugin removes its tables and settings, unless you choose to keep them.
Whether your site meets the GDPR depends on far more than one plugin, so that part is still yours to check. This plugin’s share of it is small and easy to explain in your privacy policy.
External services
None. This plugin does not connect to any third-party service.
Trademarks
Google reCAPTCHA, Cloudflare Turnstile, hCaptcha, Friendly Captcha, Akismet, CleanTalk, WooCommerce, Elementor, Contact Form 7, WPForms and the other form plugins named on this page are trademarks of their owners. This plugin is not affiliated with or endorsed by any of them.
Developer hooks
- mjscp_form_enabled (filter): enable or disable a form key.
- mjscp_pre_check (filter): short-circuit verification. Gets the form key and an array with the form plugin’s form ID.
- mjscp_score (filter): adjust the spam score.
- mjscp_error_message (filter): change the message shown on failure.
- mjscp_is_allowlisted (filter): allowlist an IP programmatically.
- mjscp_auto_attach_selectors (filter): attach the widget to extra forms by CSS selector.
- mjscp_max_number (filter): fine-tune difficulty.
- mjscp_degraded_limits (filter): how many submissions an hour may pass when the check can’t run, per IP ( per_ip, default 3) and for the whole site ( site, default 50).
- mjscp_native_{slug} (filter): true when this plugin protects that form plugin on the current request, for example mjscp_native_fluentforms. MJSCP_Plugin::has_native( 'fluentforms' ) gives the same answer. Code that connected a form plugin by hand can check it and switch itself off.
- mjscp_checked (action): runs after each verification, with the result, form key, IP, status ( pass, block or degraded ) and form ID.