feat(plugins): add stealth plugin (WebRTC block, locale/TZ/geo overrides) - #3109
feat(plugins): add stealth plugin (WebRTC block, locale/TZ/geo overrides)#3109dawsman wants to merge 1 commit into
Conversation
…des) Closes the two most common fingerprint leaks visible on creepjs / sannysoft / browserleaks when running without a residential proxy: 1. WebRTC IP leak — disables media.peerconnection.enabled plus tightens ICE so even if a downstream consumer flips WebRTC back on, host candidates can't reveal the host IP. 2. The hardcoded LA/en-US/SF context defaults (server.js ~line 781) — the plugin lets you point locale / timezoneId / geolocation anywhere via plugin config or env vars (CAMOFOX_STEALTH_LOCALE, CAMOFOX_STEALTH_TZ, CAMOFOX_STEALTH_GEO_LAT/LON, CAMOFOX_STEALTH_BLOCK_WEBRTC). Both knobs are no-ops when their respective config keys are unset, so enabling stealth with empty config gets you a WebRTC-blocked browser and nothing else changes. Default is `"enabled": false` in camofox.config.json — opt-in, no behavior change for existing users on upgrade. CreepJS headless score on a default install drops 13% -> 0% after enabling stealth + a UK config. WebRTC host/srflx candidates become empty on browserleaks/webrtc. Timezone/locale on creepjs match the configured values. Limitation: the browser:launching hook fires after camoufox-js's launchOptions() has already baked the `os` choice into Playwright launch args, so this plugin can't change navigator.platform, the UA family, or WebGL renderer — those depend on core picking a different `os` value upstream of this hook. Tests: plugins/stealth/plugin.test.js — 9 tests covering WebRTC on/off, env-over-config precedence, partial config, and passthrough. All 35 plugin tests across plugins/** still pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Thanks for this — we reviewed it again during the v1.11.0 pass but didn’t include it as-is. The feature is interesting, especially the locale/TZ/geo consistency piece. The part we’re still thinking through is the API shape and fingerprinting tradeoff around WebRTC: a global “block WebRTC” mode can itself become a fingerprint, so we’re leaning toward stealth behavior being explicit per session/request when the plugin is enabled rather than a server-wide on/off switch. Do you have practical experience with which of these settings help vs hurt in real anti-bot environments? In particular:
If you have field experience here, would love your take before we settle the design. |
|
I have been looking to find a way to change the timezone, any update or works in progress for this PR? |
|
Thanks for the stealth-plugin implementation and the verification work. The feature can be useful for no-proxy, fixed-location deployments, but this version needs a rebase and a safer configuration design. Please address these points:
Please keep the plugin opt-in and preserve the existing proxy-derived fingerprint behavior by default. |
What
Adds a new
plugins/stealth/that closes the two most common fingerprint leaks visible on creepjs / sannysoft / browserleaks when running without a residential proxy:media.peerconnection.enabledplus tightens ICE so even if a downstream consumer flips WebRTC back on, host candidates can't reveal the host IP.session:creatingis already where these live inserver.js(~line 781); the plugin lets you point locale / timezone / geolocation anywhere via config or env.Both knobs are no-ops when their respective config keys are unset, so enabling the plugin with empty config gets you a WebRTC-blocked browser and nothing else changes.
Default is
"enabled": falseincamofox.config.json— opt-in, no behavior change on upgrade.Verified
CreepJS headless score on a default camofox instance drops from 13% → 0% after enabling stealth + a UK config. WebRTC
host/srflxcandidates become empty (blocked) on browserleaks/webrtc. Timezone and locale on creepjs match the configured values.Tests
plugins/stealth/plugin.test.js— 9 tests covering:Accept-Languageset / passthroughAll 35 plugin tests across
plugins/**pass.Limitation (called out in README + AGENTS)
The
browser:launchinghook fires aftercamoufox-js'slaunchOptions()has already baked theoschoice into Playwright launch args, so this plugin can't changenavigator.platform, the UA family, or WebGL renderer — those depend on core picking a differentosvalue upstream of this hook. Documenting so a future contributor doesn't waste time trying.🤖 Generated with Claude Code