stealth: keep the Chrome 145 identity consistent across TLS, JS, and WebGL

Stealth mode forced a Linux navigator UA and platform but reported Windows
in userAgentData.getHighEntropyValues and served Windows Direct3D11 WebGL
renderers, a combination no real Linux Chrome ever produces and that
cross-layer fingerprint checks flag. Present one consistent Windows Chrome
145 identity instead: the wreq emulation uses Platform::Windows, and the
navigator surfaces read the UA and platform from shared constants so the
HTTP User-Agent header, sec-ch-ua-platform, navigator.userAgent, and
userAgentData all agree. userAgentData brands are now derived from the
Chrome major version via Chromium's GREASE algorithm rather than a single
hardcoded token, and a Linux WebGL renderer pool is added so a Linux UA can
never report a Direct3D11 renderer.
This commit is contained in:
SGavrl committed 2026-06-22 22:19:16 +00:00
1 parent dc780d77e4
commit 4309935abd
4 files changed
+74 -39

No files matched your search

+13 -2
View File
@@ -19,7 +19,18 @@ use crate::client::{Response, ObscuraNetError};
#[cfg(feature = "stealth")]
pub const STEALTH_USER_AGENT: &str =
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36";
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36";
// The wreq emulation (Profile::Chrome145, Platform::Windows) sends this exact
// UA and sec-ch-ua-platform "Windows" on the wire. navigator has to report the
// same identity, otherwise the TLS/HTTP layer and the JS layer disagree and a
// site cross-checks the mismatch as a bot signal.
#[cfg(feature = "stealth")]
pub const STEALTH_NAVIGATOR_PLATFORM: &str = "Win32";
#[cfg(feature = "stealth")]
pub const STEALTH_UA_PLATFORM: &str = "Windows";
#[cfg(feature = "stealth")]
pub const STEALTH_UA_PLATFORM_VERSION: &str = "15.0.0";
#[cfg(feature = "stealth")]
pub struct StealthHttpClient {
@@ -38,7 +49,7 @@ impl StealthHttpClient {
pub fn with_proxy(cookie_jar: Arc<CookieJar>, proxy_url: Option<&str>) -> Self {
let emulation_opts = wreq_util::Emulation::builder()
.profile(wreq_util::Profile::Chrome145)
.platform(wreq_util::Platform::Linux)
.platform(wreq_util::Platform::Windows)
.build();
let mut builder = wreq::Client::builder()