CaptchaCore

Description

CaptchaCore protects WordPress forms against bots and spam without showing image puzzles and without tracking your visitors.

Instead of asking people to identify traffic lights, the browser solves a small cryptographic computation in the background while the plugin observes whether the interaction looks human. A single visitor never notices it. A bot farm sending millions of requests pays for every single one.

  • Proof of work (SHA-256) in a web worker, so the interface never blocks
  • Behavioural and environment signals: mouse movement, typing rhythm, scrolling, canvas timing, WebGL renderer
  • No cookies and no image puzzles in normal operation
  • Processing on our own servers in Germany, no transfer to the United States
  • Widget of 16 KB gzip with no external dependencies
  • Keyboard operable and marked up for screen readers

Integrations

WordPress core:

  • Login form (also custom login forms rendered by wp_login_form)
  • Registration
  • Lost password
  • Comments and WooCommerce product reviews

WooCommerce (each one switchable):

  • Login and registration on the My Account page
  • Lost password on the My Account page
  • Checkout, on the classic checkout page ([woocommerce_checkout] shortcode). The block-based checkout is not supported yet; the settings page tells you if your shop uses it.

Form builders and page builders:

  • Formidable Forms — a native field type you drag into any form
  • Elementor — a CaptchaCore widget for the page builder and a field for Elementor Pro forms
  • Contact Form 7 — the form tag [captchacore], or added automatically in front of the submit button of every form

Beyond WordPress, the same service has packages for Laravel and Symfony, a plugin for WoltLab Suite and a REST API for everything else: https://captchacore.eu/docs/integrationen

The plugin ships with English source strings and is ready for translation on translate.wordpress.org.

CaptchaCore is a hosted service. The plugin does nothing until you enter your own credentials, which you can create free of charge for private websites.

External services

This plugin connects your site to CaptchaCore, a service operated by SpeedIT Solutions UG (haftungsbeschränkt), Isernhagen, Germany. Without that service the plugin cannot verify anything. It stays inactive until you enter your own credentials in the settings.

1. Form verification — https://api.captchacore.eu

When: every time one of the forms you protect is submitted (login, registration, comment, lost password, WooCommerce account forms and checkout, Formidable, Elementor, Contact Form 7).
What is sent: the token created by the widget, the type of the form, the IP address of the visitor, the page URL without its query string, and the visitor’s Accept-Language and Sec-Fetch-Site request headers (forwarded as X-Forwarded-Accept-Language and X-Forwarded-Sec-Fetch-Site).
Why: to decide whether the request comes from a human or from a bot.
The service never stores IP addresses in plain text: only truncated (IPv4 /24, IPv6 /48) and as a hash with a random salt that changes every 6 hours. These IP-related fields are cleared after 30 days; the remaining statistics without personal data are kept for 7 to 365 days depending on your plan.

2. Delivery of the widget script — https://src-eu.captchacore.eu (default) or https://src.captchacore.eu (optional, worldwide)

When: on every page that contains a protected form.
What is sent: the usual connection data of a file request, meaning the IP address and the browser identification.
Why: to deliver the JavaScript file of the widget. The default endpoint uses servers in the EU only. Enable the worldwide endpoint only if you need it.
If the file cannot be loaded from there, the plugin loads it once from https://captchacore.eu instead (same data). If you run the service yourself, enter your own address under “Widget source”; the widget is then loaded from there only.

3. Requests from the visitor’s browser — https://api.captchacore.eu/api/v2/challenge and /api/v2/precheck

When: on pages with a protected form, when the widget starts its check and before the form is submitted.
What is sent: the challenge request carries your public site key and the form type; the pre-check sends the widget token directly to CaptchaCore. The token contains the proof-of-work solution, condensed behaviour metrics (counters, timings and entropy values — no raw mouse paths, no key values, no form content), the user agent and technical environment characteristics used for bot detection (for example the webdriver flag, number of plugins and languages, screen size, number of CPU cores, whether software rendering is used). As with any request, the IP address of the visitor is visible to the service.
Why: to issue the proof-of-work task and to check the token early. The widget sends these requests without cookies and stores nothing in the browser.

4. Availability check

When: only inside the WordPress admin area, when you open the settings page — the plugin asks the CaptchaCore service whether your credentials work.
What is sent: your secret key for authentication. No visitor data.
Current availability of the service and past incidents: https://captchacore.eu/status

Nothing else is transmitted. The plugin sets no cookies, sends no usage statistics and reports no data about your website to us.

Terms of use: https://captchacore.eu/seite/nutzungsbedingungen
Privacy policy: https://captchacore.eu/seite/datenschutz
Data processing agreement under Art. 28 GDPR: https://captchacore.eu/seite/dsgvo

Installation

  1. Upload the plugin under Plugins > Add New
  2. Activate the plugin
  3. Open Settings > CaptchaCore
  4. Enter the service URL, the site key and the secret key

You can create an account and a key pair at https://captchacore.eu — free of charge for private websites.

FAQ

Do I need an entry in my cookie banner?

No. Neither the plugin nor the widget sets a cookie. Only the under-attack mode of the service sets a short-lived technical session cookie, which is strictly necessary for operation. CaptchaCore still belongs in your privacy policy; a ready-made passage is available at https://captchacore.eu/seite/datenschutz

What happens if the service cannot be reached?

You decide. The default is fail-open: forms are let through and the incident is logged. If you prefer to block instead, switch fail-open off in the settings. Whether the service is currently affected by an incident is shown on the public status page: https://captchacore.eu/status

Does the plugin work behind Cloudflare or a reverse proxy?

Yes. Enable the option “Behind reverse proxy / CDN” in the settings. Without that option the plugin deliberately uses only the direct connection IP, because proxy headers could otherwise be forged by any visitor. Proxies with private addresses and Cloudflare are recognised automatically; a proxy with another public IP address goes into “Trusted proxies”.

Does it work without JavaScript?

No. Proof of work and behavioural analysis need JavaScript. For visitors without it, your fail-open setting decides whether the submission is accepted or rejected.

Does it work with the WooCommerce Checkout block?

Not yet. The block does not submit a form but sends JSON to the Store API, so the token never reaches the server. Switch the checkout page to the classic [woocommerce_checkout] shortcode, or leave the checkout unprotected and protect the account forms only. The settings page shows a note when your checkout uses the block.

How do I protect Contact Form 7?

Enable “Contact Form 7” under Settings > CaptchaCore. By default the widget is added in front of the submit button of every form. To choose the position yourself, put the form tag [captchacore] into the form; if you switch off “add automatically”, only forms with the tag are checked. A failed check is reported like spam: no mail is sent and the visitor sees a short message asking to send the form again.

Can I still log in with apps over XML-RPC?

Not with your normal password while the login form is protected: XML-RPC requests carry no CAPTCHA token and are rejected. Use an application password (Users > Profile) for such apps; those keep working.

Is the service free?

For private websites, permanently. Commercial plans start above that. See https://captchacore.eu/pricing

Reviews

There are no reviews for this plugin.

Contributors & Developers

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

Contributors

Translate “CaptchaCore” into your language.

Interested in development?

Browse the code, check out the SVN repository, or subscribe to the development log by RSS.

Changelog

2.6.4

  • Fix: with the core login protected, logins on the WooCommerce My Account and checkout pages failed every time unless the WooCommerce login was protected as well. They are now only checked when the WooCommerce login is protected.
  • Fix: login forms rendered by wp_login_form() (shortcodes, widgets, themes) now show the widget instead of rejecting every login.
  • Security: with “Behind a reverse proxy or CDN” enabled, forwarding headers are only accepted from trusted proxies: private addresses, Cloudflare and the new setting “Trusted proxies”. X-Forwarded-For is read from the right, and CF-Connecting-IP only counts when the request really comes from Cloudflare. Before, a visitor could choose the IP address reported to the risk engine.
  • Fix: the local limit of 30 checks per visitor IP now uses a fixed one-minute window and counts failed checks only, so visitors sharing an IP address are no longer locked out during normal use. The settings page warns when the site is behind Cloudflare but the proxy option is off.
  • Security: the Elementor editor preview escapes the widget label.
  • Fix: the self-updater no longer causes a fatal error when another plugin resets the update information.
  • Uninstall also removes the WooCommerce settings and the short-lived limit entries.
  • New: Contact Form 7 integration. Form tag [captchacore], or added automatically in front of the submit button (switchable). The token is checked in CF7’s spam filter; a failed check sends no mail and shows a clear message.
  • Fix: the widget of the classic WooCommerce checkout is now placed below the billing details instead of inside the payment section. WooCommerce replaces that section via AJAX on every change, which removed the widget; under attack mode the click check disappeared and “Place order” did nothing.
  • Fix: the login widget in the collapsed “Returning customer?” form on the checkout page only starts when the form is used, instead of running a second check next to the checkout.
  • Fix: the comment widget is shown in block themes (for example Twenty Twenty-Five). It now uses the comment_form_submit_field filter, which the Comments block does not override.
  • Fix: no more “translation loading triggered too early” notice (_load_textdomain_just_in_time) on sites with WooCommerce.
  • Security: new installs protect the WooCommerce login together with the WordPress login when WooCommerce is active. Existing settings are not changed, but the settings page warns when the WordPress login is protected and the WooCommerce login is not.
  • New: optional setting “Widget source” and filter captchacore_widget_src for self-hosted services. If the widget script cannot be loaded, it is loaded once from the CaptchaCore server instead (without an inline handler, so strict Content Security Policies keep working).
  • German translation: remaining messages use the formal form of address (Sie); sites set to “Deutsch (Sie)” now get the German translation as well. One missing translation added.
  • Settings: the login option explains that XML-RPC logins without an application password are rejected.

2.6.3

  • Security: the login CAPTCHA now runs after WordPress has checked the password (priority 30). Before, WordPress replaced the CAPTCHA error on wp-login.php and XML-RPC, so the check had no effect. A failed CAPTCHA now always returns the same message, whether or not the password was right.
  • Security: the lost-password CAPTCHA can no longer be skipped by adding the WooCommerce field wc_reset_password to a request to wp-login.php.
  • WooCommerce: login and checkout with account creation check the token only once per request (no false rejections).
  • Backend: comment replies by moderators and “send password reset” from the user list are not blocked any more.
  • Updates are only fetched over HTTPS.
  • Security: every protected form now requests its challenge with its own form type (login, register, password_reset, comment, checkout, elementor, formidable), so stricter profiles for single forms apply.
  • Security: a rate-limited answer (HTTP 429) from the service now blocks the request instead of letting it through. In addition, the plugin allows at most 30 CAPTCHA checks per visitor IP and minute.

2.6.2

  • German translation: formal form of address (Sie) throughout.
  • Settings: the EU-only widget endpoint is now described precisely as delivery via servers in EU member states.

2.6.1

  • Security: fail-open now applies only when the service is unreachable or overloaded (timeout, 5xx, 408, 429). A request the service rejects (4xx) is always blocked.
  • The widget script now loads only on pages that actually show a protected form. Previously, protecting comments, WooCommerce forms or using Elementor loaded it on every front-end page.

2.6.0

  • WooCommerce: captcha for login, registration and lost password on the My Account page and for the classic checkout — each form switchable, all off by default
  • WooCommerce product reviews are covered by the comment protection
  • Lost-password requests from the WooCommerce form are no longer rejected when only the core form is protected
  • readme: full list of integrations

2.5.1

  • Scripts and styles are now enqueued via wp_enqueue_script/wp_enqueue_style — no inline script or style tags remain
  • Forms are marked by an enqueued script instead of inline snippets (js/captchacore-forms.js)
  • Translation files are no longer bundled in the WordPress.org build; translations come from translate.wordpress.org

2.5.0

  • The self-updater is now optional and only part of the build distributed directly from captchacore.eu. The build for the plugin directory ships without it, because updating from foreign servers is not allowed there.
  • Security: proxy headers (X-Forwarded-For, X-Real-IP, CF-Connecting-IP) are only evaluated when the new option “Behind reverse proxy / CDN” is enabled. Before that, any visitor could choose the IP address reported to the risk engine and bypass IP reputation.
  • All translated output is now escaped.
  • The reported page URL uses the actual scheme and no longer contains a query string.
  • readme: added the section about the external services in use, added the license URI, reduced the tags to five, rewritten in English.

2.4.2

  • The login hook moved to authenticate with priority 5, so it now sees every login attempt, including those with usernames that do not exist. Previously about 80 percent of brute force attempts bypassed the captcha.
  • Token-less POST attempts are reported to the CaptchaCore server once per IP per minute for the audit log, throttled through a transient so brute force bots cannot amplify API traffic.

2.4.1

  • Fixed “captcha required” in Formidable Forms although the verification tick was shown. Formidable considered the field empty because the token is sent separately, so an additional item_meta hidden input is now rendered.
  • Header forwarding for server-side bot detection (Sec-Fetch-Site, Accept-Language), which improves the detection of scripted clients.

2.4.0

  • Version 2 of the API is now the default and the only supported version.
  • Adaptive risk engine with site profiles and form policies.
  • Confidence score and reason codes in the response.
  • EdDSA-signed tokens and bindings that tie a token to origin, site and form.
  • Four-level under-attack mode with step-up challenges and memory-hard proof of work.
  • IP reputation and campaign detection integrated.

Older entries are documented at https://captchacore.eu/docs