Skip to content

fix(captcha): make English matcher additive - #2721

Merged
esokullu merged 3 commits into
webbrain-one:mainfrom
alectimison-maker:fix/captcha-additive-matcher
Aug 10, 2026
Merged

fix(captcha): make English matcher additive#2721
esokullu merged 3 commits into
webbrain-one:mainfrom
alectimison-maker:fix/captcha-additive-matcher

Conversation

@alectimison-maker

@alectimison-maker alectimison-maker commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • keep one canonical English CAPTCHA label pattern per browser build and inject it into the serialized DOM preflight and candidate detector
  • remove the allowGenericFailure path that promoted unrelated application failures such as email verification errors to CAPTCHA evidence
  • treat the English matcher as additive evidence: its absence cannot clear or reset a gate backed by an exact widget identity or a language-neutral active frame
  • let an exact token clear a manually completed recognized widget, including the hCaptcha compatibility response field
  • ignore response-token state from widget candidates that were not correlated to the active gate
  • add source-count and Chrome/Firefox parity coverage so serialized matcher copies cannot drift back in

Why

#505 identified multiple independent copies of the English matcher across the accessibility-tree, preflight, and frame-detection paths. Those copies could drift, and the active-gate-only generic-failure mode let unrelated renamed dialogs affect CAPTCHA routing.

This PR keeps the English matcher as a useful positive fallback for unrecognized or in-house challenges. It does not add a multilingual phrase table and does not include full-page Cloudflare managed-challenge detection.

This is the planned follow-up to #2720. The branch now includes current main at 18c2d652; the conflict resolution preserves #2720 token/frame authority, uses a full read-only preflight for manual completion, and does not restore legacy read-inference flags.

Verification

  • node test/run.js — 1579 passed, 0 failed
  • npm run test:toolbar-guard — 33/33 passed
  • npm run test:security — 60/60 passed
  • Chrome and Firefox CAPTCHA gate helpers, frame runtime, and merged transition block retain parity

Part of #505.

@vercel

vercel Bot commented Aug 9, 2026

Copy link
Copy Markdown

@alectimison-maker is attempting to deploy a commit to the esokullu's projects Team on Vercel.

A member of the Team first needs to authorize it.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Consolidates CAPTCHA label matching and makes English text additive to language-neutral widget/frame evidence.

Changes:

  • Centralizes and injects the English CAPTCHA matcher.
  • Removes generic verification-failure matching.
  • Extends token-based clearance and adds parity/regression coverage.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
test/run.js Adds matcher, gate-state, token, and parity tests.
src/chrome/src/agent/captcha-gate.js Defines the canonical matcher.
src/firefox/src/agent/captcha-gate.js Mirrors canonical matcher handling.
src/chrome/src/agent/captcha-frame-runtime.js Accepts injected matcher options.
src/firefox/src/agent/captcha-frame-runtime.js Mirrors runtime matcher injection.
src/chrome/src/agent/captcha-solver.js Supplies matcher options during detection.
src/firefox/src/agent/captcha-solver.js Supplies matcher options to serialized detection.
src/chrome/src/agent/agent.js Updates CAPTCHA gate transitions.
src/firefox/src/agent/agent.js Mirrors gate-transition updates.
Suppressed comments (2)

src/chrome/src/agent/agent.js:4418

  • A candidate identity does not necessarily back this gate: the state stores the selected candidate even when candidateNotCorrelated is true. Treating that unrelated identity as direct evidence means a complete read can no longer clear an English-only passkey/application dialog after it disappears, leaving the manual gate stuck until navigation. Exclude explicitly uncorrelated candidates from additive evidence.
    src/firefox/src/agent/agent.js:3853
  • A candidate identity does not necessarily back this gate: the state stores the selected candidate even when candidateNotCorrelated is true. Treating that unrelated identity as direct evidence means a complete read can no longer clear an English-only passkey/application dialog after it disappears, leaving the manual gate stuck until navigation. Exclude explicitly uncorrelated candidates from additive evidence.
    const directCaptchaEvidence = !!activeGate?.captchaCandidateIdentity
      || activeGate?.publicGate?.languageNeutralFrameTrigger === true;

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/chrome/src/agent/agent.js Outdated
Comment thread src/firefox/src/agent/agent.js Outdated
@alectimison-maker

Copy link
Copy Markdown
Contributor Author

Addressed the Copilot review in f6f1a60e: uncorrelated widget candidates no longer retain or consume response-token identity, including a defensive guard for legacy in-memory state. The Chrome/Firefox regression populates a background reCAPTCHA token beside an active passkey dialog and verifies the manual gate remains closed to automation. Validation: 1565 unit tests passed (one unrelated upstream changelog failure remains), security 60/60, toolbar guard 33/33, and WebMCP E2E passed.

@esokullu
esokullu merged commit f3a5ce8 into webbrain-one:main Aug 10, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants