Skip to content

Firefox parity Phase 1: stealth + consent (v0.16.0)#4

Merged
hamr0 merged 3 commits into
mainfrom
feat/firefox-parity-phase1
Jul 10, 2026
Merged

Firefox parity Phase 1: stealth + consent (v0.16.0)#4
hamr0 merged 3 commits into
mainfrom
feat/firefox-parity-phase1

Conversation

@hamr0

@hamr0 hamr0 commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Brings the Firefox/BiDi engine to practical parity with Chromium on the two
most agent-breaking gaps: headless bot-detection and cookie-consent walls.
First cut of the Firefox parity plan (docs/01-product/firefox-parity-plan.md).

What's in it

  • Stealth (src/stealth-firefox.js, headless-only, via BiDi script.addPreloadScript).
    A POC measured stock Firefox-under-BiDi and falsified the plan's "port
    stealth.js verbatim" assumption — Chromium's script is Chrome-shaped
    (window.chrome, Chrome plugins, SwiftShader WebGL) and would have created
    a spoof tell on Firefox. Firefox's only real tell is navigator.webdriver,
    so it gets a minimal script (webdriver + canvas noise). WEBDRIVER_PATCH /
    CANVAS_NOISE_PATCH are exported from stealth.js and shared by both engines.
  • Consent (src/consent-firefox.js). A pure walker over the reconstructed
    nested AX tree, clicking via the existing pointerClick. Multilingual
    patterns extracted to src/consent-patterns.js, shared by the CDP and BiDi
    walkers. Runs after goto() behind consent !== false, same as CDP.
  • Hardened navigator.webdriver on both engines. Found during live
    sannysoft validation: the naive override left a hasOwnProperty tell. The
    shared patch now deletes the getter off Navigator.prototype, so
    undefined + hasOwnProperty/in both false (matches a stock browser).
    Improves Chromium too.

Verification

  • Full suite 210/210, tsc --noEmit clean.
  • Unit: test/unit/consent-firefox.test.js (pure walker — scoping, priority,
    non-English, banner fallback, false-positive guard).
  • Integration: Firefox stealth (webdriver hidden pre-page-JS, no window.chrome
    spoof, hasOwnProperty tell gone) + consent auto-dismiss with a consent:false
    control that proves the test can fail; Chromium stealth extended for the
    hardened patch.
  • Live-validated on real Firefox: navigator.webdriver hidden on sannysoft
    (trio: undefined + hasOwnProperty false + in false), canvas noise stable,
    consent walker no false-positives on Google/Guardian, core snapshot fidelity
    intact.

🤖 Generated with Claude Code

hamr0 and others added 3 commits July 10, 2026 18:43
Fixes the two most agent-breaking Firefox gaps: headless bot-detection
(navigator.webdriver=true) and consent dialogs never dismissed.

Stealth: a POC measured stock Firefox-under-BiDi and falsified the plan's
"port stealth.js verbatim" assumption — Chromium's STEALTH_SCRIPT is
Chrome-shaped (window.chrome, Chrome plugins, SwiftShader WebGL) and would
create a spoof tell worse than the one removed. Firefox's only real tell is
navigator.webdriver, so it gets its own minimal script (webdriver + canvas
noise) via script.addPreloadScript, headless-only. WEBDRIVER_PATCH and
CANVAS_NOISE_PATCH are now exported from stealth.js so both engines share them
(single-sources the canvas double-XOR fix).

Consent: multilingual patterns extracted to consent-patterns.js (shared by the
CDP and BiDi walkers). consent-firefox.js is a pure walker over the
reconstructed nested AX tree, clicking via the existing pointerClick; wired
into firefox-page.goto() behind the same consent!==false flag as the CDP path.

Tests: consent-firefox unit tests (9, pure walker) + Firefox integration tests
(webdriver hidden at parse time, no window.chrome spoof, consent auto-dismiss +
a consent:false control that proves the test can fail). Full suite 209/209.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MZpPPhwXmSfN1n7uX7RAxT
Version bump + docs for the Firefox anti-detection and consent auto-dismiss
feature (committed in the preceding commit). CHANGELOG [0.16.0], context guide,
and PRD known-gaps updated to reflect that consent + stealth now work on the
Firefox/BiDi engine.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MZpPPhwXmSfN1n7uX7RAxT
A naive Object.defineProperty(navigator,'webdriver',…) hid the value but left
navigator.hasOwnProperty('webdriver')===true — a tell advanced anti-bot checks
(sannysoft "WebDriver New") detect, since real browsers keep webdriver on
Navigator.prototype. The shared WEBDRIVER_PATCH now deletes it off the
prototype, so navigator.webdriver is undefined AND hasOwnProperty/'in' are both
false, matching a stock browser. POC-verified on Chromium and Firefox.

Improves the Chromium engine too (shared patch). Regression tests added on both
paths (stealth.test.js + firefox.test.js). Found during live sannysoft
validation of the Firefox parity work.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MZpPPhwXmSfN1n7uX7RAxT
@hamr0
hamr0 merged commit fc63d59 into main Jul 10, 2026
1 check passed
@hamr0
hamr0 deleted the feat/firefox-parity-phase1 branch July 10, 2026 17:06
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.

1 participant