Captcha Changelog
Unreleased
- New: Hard-stop rate limiter — counts every GET and POST on captcha-protected surfaces (wp-login / register / lost-password / comments, WooCommerce my-account / checkout / pay-for-order, Ultimate Multisite checkout / inline-login) and replies with HTTP 429, a
Retry-Afterheader, and a randomised tarpit sleep (1–5s, hard-capped at 15s). - New:
cap_rate_limit_tarpit_min/cap_rate_limit_tarpit_maxsettings to tune the tarpit window. - New:
wu_cap_rate_limit_whitelist_ipfilter to exempt trusted IP ranges. - New:
wu_cap_rate_limit_will_blockaction that fires immediately before the hard-stop response is sent. - New: Spoof-resistant client-IP detection.
Captcha_Core::get_client_ip()(the source of truth for rate-limit bucket keys, captcha siteverifyremoteip, and statistics IP hashes) now enforces a strict trust model: REMOTE_ADDR is the floor,CF-Connecting-IPis honoured only when the immediate peer is inside a current Cloudflare IP range, andX-Forwarded-Foris honoured only when the immediate peer is in the admin-configured trusted-proxy list, with a right-to-left walk that skips trusted/CF hops before settling on the visitor IP. - New:
cap_trust_cloudflare_headerssetting (default OFF) — opt intoCF-Connecting-IPtrust when behind Cloudflare. The plugin ships a bundled Cloudflare CIDR snapshot and refreshes it weekly via wp-cron with bundled fallback if the refresh fails. - New:
cap_trusted_proxiessetting — textarea of CIDRs or bare IPs (one per line,#comments allowed) listing your own front-line proxies / load-balancers. Without this,X-Forwarded-Foris ignored even when the rate limiter is enabled. - New: First-enable auto-detection of likely Cloudflare / proxy posture with a one-click "Apply detected settings" admin notice. The plugin never overwrites your saved values; if subsequent traffic suggests your config no longer matches reality (e.g. Cloudflare changed CIDR ranges and your proxy CIDR is now stale), a non-dismissable mismatch notice surfaces the recommended update.
- Fixed: Invisible mode no longer silently downgrades
cap_security_levelto FAST — the admin's configured level is honoured. A newwu_cap_server_security_levelfilter is available for sites that want bespoke logic. - Fixed: Statistics
rate_limits_triggeredcounter now increments on every block, not only on the rare post-success backstop path. - Fixed:
Captcha_Core::get_client_ip()is now the single source of truth for visitor IP attribution across the rate limiter, captcha providers (reCAPTCHA + hCaptchasiteverify), and statistics — closing a spoofing vector where direct origin-server requests carrying a forgedCF-Connecting-IPheader would have been bucketed by the spoofed IP instead of the real peer. - Fixed: WooCommerce classic checkout rate-limit gate now fires on
template_redirect(priority 1) instead ofwoocommerce_before_checkout_form. The form-level hook never fires when the cart is empty, so flood traffic that never adds a product was bypassing the limiter entirely. - Fixed: WooCommerce pay-for-order rate-limit gate now fires on
template_redirectinstead ofwoocommerce_before_pay_action. The latter only fires afterwp_verify_nonce('woocommerce-pay')succeeds, which means unauth attackers (the actual threat model) never triggered the limiter. - Fixed: WooCommerce Store API (blocks) checkout rate-limit gate now fires on
rest_pre_dispatchinstead ofwoocommerce_store_api_checkout_update_order_from_request. The latter only fires after Store API validates the cart and billing fields, so unauth bots got a 400 from the validator and never tripped the limiter. - Fixed: Ultimate Multisite inline-login rate-limit gate now fires on
wu_ajax_nopriv_wu_inline_loginpriority 1 (and the logged-in mirror) instead ofwu_before_inline_login. The latter only fires aftercheck_ajax_referer('wu_checkout')succeeds, so unauth bots without a valid wu_checkout nonce got a 403 and never tripped the limiter. - Fixed:
Rate_Limiter::enforce()now applies a once-per-request guard keyed bysurface|ip, so upstream hooks that fire twice per render (notablywu_setup_checkoutin Ultimate Multisite) no longer halve the effective rate-limit threshold. - Fixed: Rate-limit surface gates no longer consult
Captcha_Core::is_whitelisted()(wu_captcha_whitelistedfilter). That filter signals "captcha already handled by another surface" and is orthogonal to flood protection — the WooCommerce integration was hooking it to skip the WordPress login captcha when a Woo nonce was present, which bled into rate counting and let Woo POSTs avoid the limiter. The rate-limit-specificwu_cap_rate_limit_whitelist_ipfilter is the only bypass that now applies.
Version: 1.4.2-beta.1 - Released on 2026-05-09
- Fixed: Cap captcha invisible-mode WASM solver race that could cause
missing_tokenerrors on form submission across all protected surfaces (WPU wizard, wp-login, register/lostpassword, comments, WC login/register/lostpassword, WC classic + blocks checkout, WPU custom login element). Submit-time gating is now applied uniformly via a sharedwindow.WUCaphelper. (#110)
Version: 1.4.1 - Released on 2026-05-07
- Fixed: Prevent cap-widget from adding duplicate cap-token to form payload (#105)
- Fixed: Comments Form captcha protection is now enabled by default (#104)
- Fixed: Login now shows a clear captcha error message instead of "Something went wrong" (#84)
- Fixed: Captcha re-validation is now skipped during 2FA OTP submission to prevent user lockouts (#82)
Version: 1.4.0 - Released on 2026-05-05
- New: Inline login captcha — captcha is now enforced on the Ultimate Multisite inline login form element, blocking bot logins during checkout
- New: Cap captcha API now routed through admin-ajax for improved reliability across all environments
- Improved: Captcha integration rebuilt with hook-based architecture, improving theme and plugin compatibility
- Improved: Unified polymorphic validation for all captcha providers
- Improved: Composer dependencies auto-install before running the test suite (pretest npm hook)
- Improved: WooCommerce checkout E2E test coverage added
Version 1.4.0 - Released on 2026-XX-XX
- New: Rate limiter extra protection (5 attempts / 10 min, 1-hour block) — enabled by default
- New: StopForumSpam integration — zero-config, enabled by default, no API key needed
- New: Project Honey Pot http:BL integration (requires free access key)
- New: AbuseIPDB integration (requires API key)
- New: Honeypot field + timing check (sub-2-second submissions blocked as bots)
- New: User-Agent blocklist for common bot signatures
Version 1.3.10 - Released on 2026-04-17
- Fix: Checkout no longer triggers duplicate error notices when the captcha hook fires on both woocommerce_checkout_process and woocommerce_after_checkout_validation.
- Fix: Invisible Cap captcha now correctly passes through on the WooCommerce Blocks checkout path when graceful pass-through is enabled.
- Fix: Fatal TypeError when a third-party registration plugin passes null via the registration_errors filter instead of a WP_Error object.
- Fix: Checkout submit button now shows a disabled state while the WASM proof-of-work completes, covering WooCommerce (#place_order) and CartFlows (.wcf-submit-button). Timeout extended to 10 seconds for slower devices.
- Improved: Plugin autoloader now skips initialisation when Bedrock's root autoloader has already loaded the dependencies, reducing overhead on Bedrock-based WordPress installations.
Version 1.3.9 - Released on 2026-04-02
- Fix: Version constant now correctly reflects the installed addon version (was reporting core plugin version)
- New: Release validation step in deployment workflow to catch version mismatches before publishing
Version 1.3.8 - Released on 2026-03-31
- New: Automated deployment workflow for WooCommerce marketplace releases
- New: AGENTS.md with build, lint, test, and code style guidelines
- Changed: Renamed composer package to ultimate-multisite/ultimate-multisite-captcha
- Changed: Replaced trigger-docs.yml with scheduled rebuild
- Changed: Added integration test workflow via core reusable CI
Version 1.3.7 - Released on 2026-03-25
- Fix: Checkout and login no longer fail when a security plugin (WP Defender, Wordfence) or firewall blocks the captcha verification endpoint. The captcha now detects the block and lets the form submit normally.
- Fix: Checkout no longer fails when the invisible captcha proof-of-work takes longer than expected to complete. The form now waits gracefully and submits once ready.
- Fix: Invisible captcha no longer uses the heavy proof-of-work difficulty level, which was causing 5-10 second delays that defeated the purpose of being invisible.
- Fix: Captcha verification failures no longer trigger IP lockouts from security plugins like WP Defender and Wordfence. Previously, a captcha infrastructure issue could lock out legitimate users by counting each failed verification as a brute-force login attempt.
- Fixed: Cap widget attachShadow error when Vue.js re-renders DOM elements
- Fixed: WASM worker CORS error due to missing Access-Control-Allow-Origin on .wasm files
- Fixed: Added .htaccess for correct WASM MIME type and CORS headers on LiteSpeed/Apache servers
Version 1.3.6 - Released on 2026-03-06
- Fixed: Asset URLs using core plugin version instead of captcha addon version
Version 1.3.5 - Released on 2026-03-06
- New: Captcha validation for inline login on checkout forms
- New: Captcha widget rendered inside the inline login prompt
- New: Hook into
wu_before_inline_loginfilter for pre-authentication validation - New: Hook into
wu_inline_login_prompt_before_submitto render captcha in login prompt
Version: 1.3.4 - Released on 2026-XX-XX
- Fixed: CORS error when loading wasm from CDN.
Version: 1.3.3 - Released on 2026-02-03
- Fixed: XSS vulnerability in Cloudflare challenge message display (cap-login, cap-checkout, cap-unified)
- Fixed: Potential fatal error when WC() returns null during early initialization
- Fixed: Captcha not resetting on network/fetch failures in WooCommerce Blocks checkout
- Fixed: MutationObserver not detecting WooCommerce Block checkout errors for captcha reset
- Improved: Captcha no longer resets unnecessarily on routine checkout updates (shipping, coupons)
Version: 1.3.2 - Released on 2026-01-27
- Fixed: Cap widget not rendering on checkout forms using Elementor or other page builders
- Fixed: cap-widget custom element being stripped by wp_kses() sanitization
- Improved: Use callable content for checkout captcha field to bypass HTML filtering
- Improved: Simplified JavaScript with fallback for edge cases
Version: 1.3.1 - Released on 2026-01-26
- Fixed: Cap Captcha invisible mode not auto-solving on dynamic Ultimate Multisite checkout forms
- Improved: Cap checkout script now uses MutationObserver to detect dynamically loaded widgets
- Improved: Added checkout button interception to wait for token before submission
Version: 1.3.0 - Released on 2026-01-27
- New: WooCommerce Blocks checkout integration with Store API fetch interception
- New: Invisible captcha support for WooCommerce checkout (hCaptcha invisible, reCAPTCHA v2 invisible, v3)
- New: Standalone settings page for use without Ultimate Multisite
- New: Jetpack Autoloader for dependency conflict prevention
- Fixed: hCaptcha not rendering on dynamic Ultimate Multisite checkout (AJAX-loaded content)
- Fixed: Captcha not refreshing/resetting when form validation errors occur
- Fixed: hCaptcha not showing on WooCommerce checkout page
- Fixed: reCAPTCHA class not found error (added google/recaptcha PHP library)
- Improved: Error detection via WordPress hooks, MutationObserver, and AJAX interception
- Improved: Settings descriptions now include dashboard URLs for API keys
Version: 1.2.2 - Released on 2026-01-24
- Fixed: Captcha not displaying on Ultimate Multisite Login Form Element (form filter name mismatch)
- Fixed: Cap widget HTML being stripped by wp_kses() sanitization
- Fixed: JavaScript selectors not finding forms with slashes in element IDs
- Added: Filter hook
wu_kses_allowed_htmlfor classaddons to extend allowed HTML tags - Removed: Dead code JavaScript files replaced by provider-specific scripts
Version: 1.2.1 - Released on 2026-01-23
- Fixed: Cap Captcha token validation failing in multisite environments (now uses network-wide transients)
- Fixed: Captcha now renders consistently for all users regardless of login status
- Fixed: Mismatch between captcha rendering and validation that caused checkout failures
Version: 1.2.0 - Released on 2026-01-21
- New: Cap Captcha - self-hosted proof-of-work captcha, enabled by default on activation
- New: Zero-configuration protection - activate the addon and you're protected immediately
- New: Polymorphic captcha provider architecture for easy extensibility
- New: WooCommerce Store API checkout protection against card testing attacks
- New: Statistics tracking dashboard showing challenges, verifications, and blocked attacks
- New: Security level presets (Fast, Medium, Max) for Cap Captcha difficulty
- New: Abstract base classes for reCAPTCHA and hCaptcha providers
- Improved: Refactored codebase into modular provider classes
- Improved: Better separation of concerns with dedicated manager class
- Fixed: Security improvements for $_SERVER variable sanitization
- Fixed: PHPUnit test configuration for WordPress naming conventions
Version: 1.0.1 - Released on 2025-09-28
- Rename prefix to ultimate-multisite; update text domain; version bump.