fix: split stealth init scripts by browser engine and add Firefox stealth
All checks were successful
CI / vet (pull_request) Successful in 1m59s
CI / build (pull_request) Successful in 2m1s
CI / test (pull_request) Successful in 2m1s

The stealth system previously injected all 12 init scripts unconditionally
into every browser engine. Chromium-specific scripts (window.chrome stubs,
ANGLE WebGL strings, CDP cleanup, HeadlessChrome UA strip) were no-ops or
actively suspicious on Firefox, while Firefox-specific headless vectors
were unaddressed.

Split stealthInitScripts into three categories:
- stealthCommonScripts (4): webdriver, outerWidth/Height, permissions, Notification
- stealthChromiumScripts (8): existing Chromium-specific scripts
- stealthFirefoxScripts (5): new Firefox-specific stealth:
  - navigator.webdriver getOwnPropertyDescriptor hardening
  - WebGL renderer spoof with Mesa/Intel strings
  - mozInnerScreenX/Y non-zero spoof
  - navigator.hardwareConcurrency normalization
  - PDF.js plugin list override

browser_init.go now selects common + engine-specific scripts based on
opt.Browser. Tests updated with per-category validation and cross-
contamination checks.

Closes #69

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-24 01:20:40 +00:00
parent 3cc528a766
commit 34161209de
3 changed files with 378 additions and 100 deletions

View File

@@ -61,7 +61,13 @@ func initBrowser(opt BrowserOptions) (*browserInitResult, error) {
if opt.Browser == BrowserChromium {
launchArgs = append(launchArgs, stealthChromiumArgs...)
}
initScripts = append(initScripts, stealthInitScripts...)
initScripts = append(initScripts, stealthCommonScripts...)
switch opt.Browser {
case BrowserChromium:
initScripts = append(initScripts, stealthChromiumScripts...)
case BrowserFirefox:
initScripts = append(initScripts, stealthFirefoxScripts...)
}
}
launchArgs = append(launchArgs, opt.LaunchArgs...)