fix(webrtc): ship the validated proxy realness config + CI guards
Audit follow-up (2026-06-10), all validated before commit. #2 WebRTC — the shipped baseline now MATCHES the manually-validated config (behind a residential proxy: host=<uuid>.local, srflx=proxy egress, No-Leak, gathering completes, indistinguishable from vanilla Firefox on BrowserLeaks + CreepJS): - prefs baseline obfuscate_host_addresses False->True; add zoom.stealth.webrtc.disable_ipv6=True; drop the dead media.peerconnection.ice.disableIPv6 (no-op on FF150) - launcher auto-derives the proxy egress IP via _geo.prepare_session_geo (one round-trip shared with the timezone resolution) and feeds nICEr via STEALTHFOX_WEBRTC_PUBLIC_IP + STEALTHFOX_WEBRTC_DISABLE_IPV6 in _build_env (sync + async); an explicit caller env still wins. The C++ mechanisms were already in firefox-9 — this activates them, no rebuild. #1 drop orphan prefs zoom.stealth.timezone + zoom.stealth.seed (read by no C++; the live ones are juggler.timezone.override + zoom.stealth.fpp.hw_seed). #3 release title 'rev N' instead of 'rev firefox-N'. CI guards (unit, leak-safe — no real proxy/creds, the kind that would have caught this gap at zero cost): - shipped-baseline guard + no-orphan-prefs (test_webrtc_realness.py) - egress auto-derive in _build_env (test_launcher_helpers.py) - prepare_session_geo returns (tz, egress) (test_geo.py) CI keeps faking 'behind a proxy' with an in-process TCP-only SOCKS5 + RFC 5737 TEST-NET IPs; real-proxy residential realness stays a LOCAL manual gate. 449 unit pass.
This commit is contained in:
@@ -169,3 +169,38 @@ def test_default_context_includes_locale_when_set():
|
||||
def test_default_context_omits_locale_when_empty():
|
||||
ip = InvisiblePlaywright(seed=42, locale="")
|
||||
assert "locale" not in ip._default_context_kwargs()
|
||||
|
||||
|
||||
# ── InvisiblePlaywright._build_env — WebRTC egress auto-derive ─────────
|
||||
# Locks the 2026-06-10 fix: behind a proxy the launcher feeds the discovered
|
||||
# egress IP to nICEr (srflx override) + drops IPv6. Without it, a proxied
|
||||
# session's WebRTC silently fell back to leaking/blocking. Runs in tests.yml.
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_build_env_injects_webrtc_egress_when_discovered():
|
||||
ip = InvisiblePlaywright(seed=42)
|
||||
ip._webrtc_egress_ip = "203.0.113.9" # what __enter__ resolves behind a proxy
|
||||
env = ip._build_env()
|
||||
assert env["STEALTHFOX_WEBRTC_PUBLIC_IP"] == "203.0.113.9"
|
||||
assert env["STEALTHFOX_WEBRTC_DISABLE_IPV6"] == "1"
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_build_env_no_webrtc_keys_without_proxy(monkeypatch):
|
||||
monkeypatch.delenv("STEALTHFOX_WEBRTC_PUBLIC_IP", raising=False)
|
||||
ip = InvisiblePlaywright(seed=42)
|
||||
ip._webrtc_egress_ip = None # no proxy → real STUN already truthful
|
||||
env = ip._build_env()
|
||||
assert "STEALTHFOX_WEBRTC_PUBLIC_IP" not in env
|
||||
assert "STEALTHFOX_WEBRTC_DISABLE_IPV6" not in env
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_build_env_caller_env_override_wins(monkeypatch):
|
||||
monkeypatch.setenv("STEALTHFOX_WEBRTC_PUBLIC_IP", "198.51.100.5")
|
||||
ip = InvisiblePlaywright(seed=42)
|
||||
ip._webrtc_egress_ip = "203.0.113.9" # auto-discovered
|
||||
env = ip._build_env()
|
||||
assert env["STEALTHFOX_WEBRTC_PUBLIC_IP"] == "198.51.100.5" # caller wins
|
||||
assert env["STEALTHFOX_WEBRTC_DISABLE_IPV6"] == "1"
|
||||
|
||||
Reference in New Issue
Block a user