Skip to content

v1.2.0 — Proof of work + placeholder widget

Choose a tag to compare

@willybahuaud willybahuaud released this 10 Jun 20:28
· 4 commits to main since this release

What's new

Proof of work

Before this release, the captcha init endpoint was free: a bot could harvest valid tokens and field names at will, then forge a behavioral log. PoW changes the economics — every token costs CPU time first.

The init endpoint becomes two-phase: it first answers an HMAC-signed challenge that the client solves in a background Web Worker (~100–500 ms on desktop, transparent for humans), then issues the token once the solution is verified. Enabled by default (JS and endpoint ship together in the plugin, no desync risk).

Tunable via gaitcha_config:

add_filter( 'gaitcha_config', function ( $config ) {
    $config['pow_difficulty'] = 20;   // Harder if you're under attack (default: 18).
    // $config['pow'] = false;        // Or disable entirely.
    return $config;
} );

Solved challenges are consumed via WPTokenStore (anti-replay was already on by default): one solution = one token.

Placeholder widget

The captcha now appears immediately at page load as a dimmed, non-interactive placeholder — same dimensions as the final widget (zero layout shift), and nothing scrapable (no field name, no token, no hidden inputs). On the first interaction, the PoW resolves in the background and the placeholder upgrades in place.

Fixed

  • Ninja Forms (#2) — form could never be resubmitted after a first attempt without checking the captcha. NF kept a stale field error in its Backbone model; the checkbox lives outside that model so checking it never lifted the error, and NF blocked the resubmission client-side. The adapter now clears the field errors when the widget gets checked. Thanks to @clementpolito for the detailed report.

Under the hood

  • REST endpoint forwards the decoded JSON request body to Gaitcha\AbstractEndpoint::handleInit() (two-phase init wiring)
  • Core dependency: willybahuaud/gaitcha ^0.7
  • Bundled JS includes the PoW solver (inline SHA-256 in a Blob-based Web Worker, with a chunked main-thread fallback for strict CSP setups)

Installation

Auto-update from the WordPress dashboard, or download the ZIP and upload via Plugins > Add New > Upload.