stealth: gate JS behaviours, upgrade wreq, fix fp consistency
wreq upgraded to 6.0.0-rc.29 and wreq-util to 3.0.0-rc.12 to apply the latest Chrome 145 TLS fingerprint (16 cipher suites, proper extension order, ALPS, GREASE). __obscura_stealth global variable introduced and passed from Rust to JS, allowing stealth-specific JS behaviors to run only when the stealth flag is enabled. Tightened hardwareConcurrency and deviceMemory pools in stealth mode to desktop-realistic values (e.g. min 4GB RAM, 4 cores), eliminating mobile-tier values that leak the spoof. navigator.userAgentData and getHighEntropyValues() are now overridden in stealth mode to perfectly match the sec-ch-ua header sent by wreq_util::Profile::Chrome145. Fixed usedJSHeapSize sometimes exceeding totalJSHeapSize.
This commit is contained in:
1 parent
dc2c585511
commit
56ab54e615
6 files changed
+197
-108
No files matched your search
Generated
+100
-74
@@ -8,18 +8,6 @@ version = "2.0.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ahash"
|
|
||||||
version = "0.8.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"once_cell",
|
|
||||||
"version_check",
|
|
||||||
"zerocopy",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "1.1.4"
|
version = "1.1.4"
|
||||||
@@ -44,6 +32,12 @@ dependencies = [
|
|||||||
"alloc-no-stdlib",
|
"alloc-no-stdlib",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "allocator-api2"
|
||||||
|
version = "0.2.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anstream"
|
name = "anstream"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
@@ -246,31 +240,6 @@ dependencies = [
|
|||||||
"generic-array",
|
"generic-array",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "boring-sys2"
|
|
||||||
version = "5.0.0-alpha.13"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "455d79965f5155dcc88a7abce112c3590883889131b799beda10bf9a813ed669"
|
|
||||||
dependencies = [
|
|
||||||
"bindgen 0.72.1",
|
|
||||||
"cmake",
|
|
||||||
"fs_extra",
|
|
||||||
"fslock",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "boring2"
|
|
||||||
version = "5.0.0-alpha.13"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "183ccc3854411c035410dcdbffafca62084f3a6c33f013c77e83c025d2a08a28"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"boring-sys2",
|
|
||||||
"foreign-types",
|
|
||||||
"libc",
|
|
||||||
"openssl-macros",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "brotli"
|
name = "brotli"
|
||||||
version = "8.0.3"
|
version = "8.0.3"
|
||||||
@@ -292,6 +261,31 @@ dependencies = [
|
|||||||
"alloc-stdlib",
|
"alloc-stdlib",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "btls"
|
||||||
|
version = "0.5.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2c5e60b8c8d282c86360cab651ded04ab0335a7b5390c8d34145cbeab8cacf5f"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"btls-sys",
|
||||||
|
"foreign-types",
|
||||||
|
"libc",
|
||||||
|
"openssl-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "btls-sys"
|
||||||
|
version = "0.5.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9b1b8638a2e1c38a5ae4efa90ae57e643baec35a30d03fc5b399b893adc4954b"
|
||||||
|
dependencies = [
|
||||||
|
"bindgen 0.72.1",
|
||||||
|
"cmake",
|
||||||
|
"fs_extra",
|
||||||
|
"fslock",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
version = "3.20.3"
|
version = "3.20.3"
|
||||||
@@ -789,6 +783,12 @@ version = "0.1.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "foldhash"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "foreign-types"
|
name = "foreign-types"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
@@ -1019,19 +1019,13 @@ dependencies = [
|
|||||||
"crc32fast",
|
"crc32fast",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "hashbrown"
|
|
||||||
version = "0.13.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.15.5"
|
version = "0.15.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"foldhash",
|
"foldhash 0.1.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1039,6 +1033,11 @@ name = "hashbrown"
|
|||||||
version = "0.17.1"
|
version = "0.17.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
|
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
|
||||||
|
dependencies = [
|
||||||
|
"allocator-api2",
|
||||||
|
"equivalent",
|
||||||
|
"foldhash 0.2.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
@@ -1113,7 +1112,6 @@ dependencies = [
|
|||||||
"futures-sink",
|
"futures-sink",
|
||||||
"http",
|
"http",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"parking_lot",
|
|
||||||
"slab",
|
"slab",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"tokio",
|
"tokio",
|
||||||
@@ -1428,6 +1426,15 @@ version = "0.4.32"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a"
|
checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lru"
|
||||||
|
version = "0.18.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a860605968fce16869fd239cf4237a82f3ac470723415db603b0e8b6c8d4fb9"
|
||||||
|
dependencies = [
|
||||||
|
"hashbrown 0.17.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lru-slab"
|
name = "lru-slab"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
@@ -2240,17 +2247,6 @@ version = "1.0.23"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
|
checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "schnellru"
|
|
||||||
version = "0.2.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "356285bbf17bea63d9e52e96bd18f039672ac92b55b8cb997d6162a2a37d1649"
|
|
||||||
dependencies = [
|
|
||||||
"ahash",
|
|
||||||
"cfg-if",
|
|
||||||
"hashbrown 0.13.2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
@@ -2746,12 +2742,12 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-boring2"
|
name = "tokio-btls"
|
||||||
version = "5.0.0-alpha.13"
|
version = "0.5.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0f81df1210d791f31d72d840de8fbd80b9c3cb324956523048b1413e2bd55756"
|
checksum = "2e1fd638ec35427faf3b8f412e0fdd6fae76591d79dba40f38fa667d22bc44dd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"boring2",
|
"btls",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -3550,16 +3546,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wreq"
|
name = "wreq"
|
||||||
version = "6.0.0-rc.28"
|
version = "6.0.0-rc.29"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f79937f6c4df65b3f6f78715b9de2977afe9ee3b3436483c7949a24511e25935"
|
checksum = "3f0eba5f5814a94e5f1a99156f187133464e525b66bdbc69a9627d46530af2e1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"btls",
|
||||||
"boring2",
|
"btls-sys",
|
||||||
"brotli",
|
|
||||||
"bytes",
|
"bytes",
|
||||||
"flate2",
|
|
||||||
"futures-channel",
|
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
@@ -3568,29 +3561,62 @@ dependencies = [
|
|||||||
"httparse",
|
"httparse",
|
||||||
"ipnet",
|
"ipnet",
|
||||||
"libc",
|
"libc",
|
||||||
|
"lru",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"schnellru",
|
|
||||||
"smallvec",
|
|
||||||
"socket2",
|
"socket2",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-boring2",
|
"tokio-btls",
|
||||||
"tokio-socks",
|
"tokio-socks",
|
||||||
"tower",
|
"tower",
|
||||||
"url",
|
"url",
|
||||||
"want",
|
|
||||||
"webpki-root-certs",
|
"webpki-root-certs",
|
||||||
"zstd",
|
"wreq-proto",
|
||||||
|
"wreq-rt",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wreq-proto"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a43942f024bb303f1042c9aa3c87fa1d9149f507c65db6e5220a11ccdb207387"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"futures-channel",
|
||||||
|
"futures-util",
|
||||||
|
"http",
|
||||||
|
"http-body",
|
||||||
|
"http2",
|
||||||
|
"httparse",
|
||||||
|
"pin-project-lite",
|
||||||
|
"smallvec",
|
||||||
|
"tokio",
|
||||||
|
"tokio-util",
|
||||||
|
"want",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wreq-rt"
|
||||||
|
version = "0.2.2-rc.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "99e9bce67a3fa3dd3f1503f066d86661c9caf399a763d3bd184da7afaf886c8b"
|
||||||
|
dependencies = [
|
||||||
|
"pin-project-lite",
|
||||||
|
"tokio",
|
||||||
|
"wreq-proto",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wreq-util"
|
name = "wreq-util"
|
||||||
version = "3.0.0-rc.10"
|
version = "3.0.0-rc.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6c6bbe24d28beb9ceb58b514bd6a613c759d3b706f768b9d2950d5d35b543c04"
|
checksum = "baa5d2ab72139256916ca352a3d05c53d74e1dd360052eb5ba7691033c417c65"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"brotli",
|
||||||
|
"flate2",
|
||||||
"typed-builder",
|
"typed-builder",
|
||||||
"wreq",
|
"wreq",
|
||||||
|
"zstd",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -275,6 +275,7 @@ impl Page {
|
|||||||
|
|
||||||
#[cfg(feature = "stealth")]
|
#[cfg(feature = "stealth")]
|
||||||
if self.stealth_client.is_some() {
|
if self.stealth_client.is_some() {
|
||||||
|
rt.set_stealth(true);
|
||||||
rt.set_user_agent(obscura_net::STEALTH_USER_AGENT);
|
rt.set_user_agent(obscura_net::STEALTH_USER_AGENT);
|
||||||
// Match platform to the Linux UA so navigator.platform and
|
// Match platform to the Linux UA so navigator.platform and
|
||||||
// userAgentData.platform are consistent with navigator.userAgent.
|
// userAgentData.platform are consistent with navigator.userAgent.
|
||||||
@@ -315,6 +316,8 @@ impl Page {
|
|||||||
rt.set_dom(dom);
|
rt.set_dom(dom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rt.run_page_init();
|
||||||
|
|
||||||
self.js = Some(rt);
|
self.js = Some(rt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+71
-19
@@ -14,6 +14,7 @@
|
|||||||
'__obscura_errors', '__obscura_init', '__obscura_hide_list',
|
'__obscura_errors', '__obscura_init', '__obscura_hide_list',
|
||||||
'__obscura_objects', '__obscura_oid', '__obscura_ua',
|
'__obscura_objects', '__obscura_oid', '__obscura_ua',
|
||||||
'__obscura_platform', '__obscura_ua_platform', '__obscura_ua_platform_version',
|
'__obscura_platform', '__obscura_ua_platform', '__obscura_ua_platform_version',
|
||||||
|
'__obscura_stealth',
|
||||||
'__documentReadyState__', '__currentUrl',
|
'__documentReadyState__', '__currentUrl',
|
||||||
// internal helpers (var-declared throughout the file)
|
// internal helpers (var-declared throughout the file)
|
||||||
'__processDynScriptQueue', '_markNative', '_fpRand', '_fpNoise',
|
'__processDynScriptQueue', '_markNative', '_fpRand', '_fpNoise',
|
||||||
@@ -2579,7 +2580,7 @@ globalThis.navigator = {
|
|||||||
vendor: "Google Inc.", product: "Gecko", productSub: "20030107",
|
vendor: "Google Inc.", product: "Gecko", productSub: "20030107",
|
||||||
doNotTrack: null,
|
doNotTrack: null,
|
||||||
deviceMemory: 8,
|
deviceMemory: 8,
|
||||||
connection: { effectiveType: "4g", rtt: 50, downlink: 10, saveData: false, onchange: null, addEventListener(){}, removeEventListener(){}, dispatchEvent(){return true;} },
|
connection: { effectiveType: "4g", type: "wifi", rtt: 50, downlink: 10, saveData: false, onchange: null, addEventListener(){}, removeEventListener(){}, dispatchEvent(){return true;} },
|
||||||
pdfViewerEnabled: true,
|
pdfViewerEnabled: true,
|
||||||
get plugins() {
|
get plugins() {
|
||||||
const p = new PluginArray([
|
const p = new PluginArray([
|
||||||
@@ -2604,7 +2605,7 @@ globalThis.navigator = {
|
|||||||
brands: [
|
brands: [
|
||||||
{brand: "Google Chrome", version: "145"},
|
{brand: "Google Chrome", version: "145"},
|
||||||
{brand: "Chromium", version: "145"},
|
{brand: "Chromium", version: "145"},
|
||||||
{brand: "Not=A?Brand", version: "24"},
|
{brand: "Not;A=Brand", version: "24"},
|
||||||
],
|
],
|
||||||
mobile: false,
|
mobile: false,
|
||||||
get platform() { return globalThis.__obscura_ua_platform || "Windows"; },
|
get platform() { return globalThis.__obscura_ua_platform || "Windows"; },
|
||||||
@@ -2612,8 +2613,8 @@ globalThis.navigator = {
|
|||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
architecture: "x86",
|
architecture: "x86",
|
||||||
bitness: "64",
|
bitness: "64",
|
||||||
brands: [{brand:"Google Chrome",version:"145"},{brand:"Chromium",version:"145"},{brand:"Not=A?Brand",version:"24"}],
|
brands: [{brand:"Google Chrome",version:"145"},{brand:"Chromium",version:"145"},{brand:"Not;A=Brand",version:"24"}],
|
||||||
fullVersionList: [{brand:"Google Chrome",version:"145.0.0.0"},{brand:"Chromium",version:"145.0.0.0"},{brand:"Not=A?Brand",version:"24.0.0.0"}],
|
fullVersionList: [{brand:"Google Chrome",version:"145.0.0.0"},{brand:"Chromium",version:"145.0.0.0"},{brand:"Not;A=Brand",version:"24.0.0.0"}],
|
||||||
mobile: false,
|
mobile: false,
|
||||||
model: "",
|
model: "",
|
||||||
platform: globalThis.__obscura_ua_platform || "Windows",
|
platform: globalThis.__obscura_ua_platform || "Windows",
|
||||||
@@ -5902,6 +5903,32 @@ if (typeof navigator.credentials === 'undefined') {
|
|||||||
navigator.credentials = { get(){return Promise.resolve(null);}, create(){return Promise.resolve(null);}, store(){return Promise.resolve();}, preventSilentAccess(){return Promise.resolve();} };
|
navigator.credentials = { get(){return Promise.resolve(null);}, create(){return Promise.resolve(null);}, store(){return Promise.resolve();}, preventSilentAccess(){return Promise.resolve();} };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
navigator.mediaCapabilities = {
|
||||||
|
decodingInfo(cfg) {
|
||||||
|
return Promise.resolve({ supported: true, smooth: true, powerEfficient: true, keySystemAccess: null, configuration: cfg });
|
||||||
|
},
|
||||||
|
encodingInfo(cfg) {
|
||||||
|
return Promise.resolve({ supported: true, smooth: true, powerEfficient: true, configuration: cfg });
|
||||||
|
},
|
||||||
|
};
|
||||||
|
navigator.locks = {
|
||||||
|
request(name, opts, cb) {
|
||||||
|
if (typeof opts === 'function') { cb = opts; opts = {}; }
|
||||||
|
if (typeof cb === 'function') return Promise.resolve(cb({ name, mode: (opts && opts.mode) || 'exclusive' }));
|
||||||
|
return Promise.resolve(null);
|
||||||
|
},
|
||||||
|
query() { return Promise.resolve({ held: [], pending: [] }); },
|
||||||
|
};
|
||||||
|
navigator.keyboard = {
|
||||||
|
getLayoutMap() { return Promise.resolve(new Map()); },
|
||||||
|
lock() { return Promise.resolve(); },
|
||||||
|
unlock() {},
|
||||||
|
};
|
||||||
|
navigator.gpu = { requestAdapter() { return Promise.resolve(null); } };
|
||||||
|
navigator.wakeLock = { request() { return Promise.reject(new DOMException('Not allowed', 'NotAllowedError')); } };
|
||||||
|
navigator.share = function(data) { return Promise.reject(new DOMException('Not allowed', 'NotAllowedError')); };
|
||||||
|
navigator.canShare = function() { return false; };
|
||||||
|
|
||||||
globalThis.opener = null;
|
globalThis.opener = null;
|
||||||
|
|
||||||
globalThis.Worker = class Worker {
|
globalThis.Worker = class Worker {
|
||||||
@@ -5990,16 +6017,16 @@ URL.revokeObjectURL = function(url) {
|
|||||||
globalThis.scrollTo = function(x, y) {};
|
globalThis.scrollTo = function(x, y) {};
|
||||||
globalThis.scrollBy = function(x, y) {};
|
globalThis.scrollBy = function(x, y) {};
|
||||||
globalThis.scroll = function(x, y) {};
|
globalThis.scroll = function(x, y) {};
|
||||||
globalThis.focus = function() {};
|
globalThis.focus = function() {}; _markNative(globalThis.focus);
|
||||||
globalThis.blur = function() {};
|
globalThis.blur = function() {}; _markNative(globalThis.blur);
|
||||||
globalThis.print = function() {};
|
globalThis.print = function() {}; _markNative(globalThis.print);
|
||||||
globalThis.alert = function() {};
|
globalThis.alert = function() {}; _markNative(globalThis.alert);
|
||||||
globalThis.confirm = function() { return true; };
|
globalThis.confirm = function() { return true; }; _markNative(globalThis.confirm);
|
||||||
globalThis.prompt = function() { return null; };
|
globalThis.prompt = function() { return null; }; _markNative(globalThis.prompt);
|
||||||
globalThis.open = function() { return null; };
|
globalThis.open = function() { return null; }; _markNative(globalThis.open);
|
||||||
globalThis.close = function() {};
|
globalThis.close = function() {}; _markNative(globalThis.close);
|
||||||
globalThis.stop = function() {};
|
globalThis.stop = function() {}; _markNative(globalThis.stop);
|
||||||
globalThis.postMessage = function() {};
|
globalThis.postMessage = function() {}; _markNative(globalThis.postMessage);
|
||||||
globalThis.requestIdleCallback = globalThis.requestIdleCallback || function(cb) { return setTimeout(cb, 0); };
|
globalThis.requestIdleCallback = globalThis.requestIdleCallback || function(cb) { return setTimeout(cb, 0); };
|
||||||
globalThis.cancelIdleCallback = globalThis.cancelIdleCallback || function(id) { clearTimeout(id); };
|
globalThis.cancelIdleCallback = globalThis.cancelIdleCallback || function(id) { clearTimeout(id); };
|
||||||
if (typeof ReadableStream === 'undefined') {
|
if (typeof ReadableStream === 'undefined') {
|
||||||
@@ -6453,20 +6480,45 @@ globalThis.__obscura_init = function() {
|
|||||||
globalThis.innerWidth = sw; globalThis.innerHeight = sh - 80;
|
globalThis.innerWidth = sw; globalThis.innerHeight = sh - 80;
|
||||||
globalThis.outerWidth = sw; globalThis.outerHeight = sh;
|
globalThis.outerWidth = sw; globalThis.outerHeight = sh;
|
||||||
|
|
||||||
var hwValues = [2, 4, 6, 8, 12, 16];
|
var hwValues = globalThis.__obscura_stealth ? [4, 6, 8, 12, 16] : [2, 4, 6, 8, 12, 16];
|
||||||
globalThis.navigator.hardwareConcurrency = hwValues[Math.floor(_fpRand(400) * hwValues.length)];
|
globalThis.navigator.hardwareConcurrency = hwValues[Math.floor(_fpRand(400) * hwValues.length)];
|
||||||
var memValues = [0.25, 0.5, 1, 2, 4, 8];
|
var memValues = globalThis.__obscura_stealth ? [4, 8] : [0.25, 0.5, 1, 2, 4, 8];
|
||||||
globalThis.navigator.deviceMemory = memValues[Math.floor(_fpRand(401) * memValues.length)];
|
globalThis.navigator.deviceMemory = memValues[Math.floor(_fpRand(401) * memValues.length)];
|
||||||
|
|
||||||
const t0 = Date.now() + Math.floor(_fpRand(641) * 100) - 50;
|
const t0 = Date.now() + Math.floor(_fpRand(641) * 100) - 50;
|
||||||
globalThis.performance.timeOrigin = t0;
|
globalThis.performance.timeOrigin = t0;
|
||||||
globalThis.performance.timing = { navigationStart: t0, domContentLoadedEventEnd: t0, loadEventEnd: t0 };
|
globalThis.performance.timing = { navigationStart: t0, domContentLoadedEventEnd: t0, loadEventEnd: t0 };
|
||||||
|
var _totalHeap = 15000000 + Math.floor(_fpRand(620) * 85000000);
|
||||||
globalThis.performance.memory = {
|
globalThis.performance.memory = {
|
||||||
jsHeapSizeLimit: 2172649472,
|
jsHeapSizeLimit: 2172649472,
|
||||||
totalJSHeapSize: 15000000 + Math.floor(_fpRand(620) * 85000000),
|
totalJSHeapSize: _totalHeap,
|
||||||
usedJSHeapSize: 8000000 + Math.floor(_fpRand(621) * 42000000),
|
usedJSHeapSize: Math.floor(_totalHeap * (0.3 + _fpRand(621) * 0.5)),
|
||||||
};
|
};
|
||||||
globalThis.Notification.permission = _fpRand(630) > 0.5 ? "granted" : "default";
|
globalThis.Notification.permission = "default";
|
||||||
|
|
||||||
|
if (globalThis.__obscura_stealth) {
|
||||||
|
var _stealthBrands = [
|
||||||
|
{brand: "Not:A-Brand", version: "99"},
|
||||||
|
{brand: "Google Chrome", version: "145"},
|
||||||
|
{brand: "Chromium", version: "145"},
|
||||||
|
];
|
||||||
|
globalThis.navigator.userAgentData.brands = _stealthBrands;
|
||||||
|
globalThis.navigator.userAgentData.getHighEntropyValues = function(hints) {
|
||||||
|
return Promise.resolve({
|
||||||
|
architecture: "x86", bitness: "64",
|
||||||
|
brands: _stealthBrands,
|
||||||
|
fullVersionList: [
|
||||||
|
{brand:"Not:A-Brand",version:"99.0.0.0"},
|
||||||
|
{brand:"Google Chrome",version:"145.0.0.0"},
|
||||||
|
{brand:"Chromium",version:"145.0.0.0"},
|
||||||
|
],
|
||||||
|
mobile: false, model: "",
|
||||||
|
platform: "Linux",
|
||||||
|
platformVersion: "6.1.0",
|
||||||
|
uaFullVersion: "145.0.0.0",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Hide internals (_*, obscura, Obscura). The set of keys is static at
|
// Hide internals (_*, obscura, Obscura). The set of keys is static at
|
||||||
// snapshot-build time, so we precompute it ONCE below (after this
|
// snapshot-build time, so we precompute it ONCE below (after this
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ impl ObscuraJsRuntime {
|
|||||||
runtime
|
runtime
|
||||||
.execute_script(
|
.execute_script(
|
||||||
"<obscura:init>",
|
"<obscura:init>",
|
||||||
"globalThis.__obscura_objects = {}; globalThis.__obscura_oid = 0; globalThis.__obscura_init();".to_string(),
|
"globalThis.__obscura_objects = {}; globalThis.__obscura_oid = 0;".to_string(),
|
||||||
)
|
)
|
||||||
.expect("init should not fail");
|
.expect("init should not fail");
|
||||||
|
|
||||||
@@ -220,6 +220,22 @@ impl ObscuraJsRuntime {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_stealth(&mut self, enabled: bool) {
|
||||||
|
let _ = self.runtime.execute_script(
|
||||||
|
"<set-stealth>",
|
||||||
|
format!("globalThis.__obscura_stealth = {};", enabled),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Run __obscura_init() after all per-page properties (UA, platform, stealth, etc.)
|
||||||
|
/// have been set. Must be called once per page setup, after all set_* methods.
|
||||||
|
pub fn run_page_init(&mut self) {
|
||||||
|
let _ = self.runtime.execute_script(
|
||||||
|
"<obscura:page-init>",
|
||||||
|
"globalThis.__obscura_init();".to_string(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// Override the coordinates the navigator.geolocation shim reports. The
|
/// Override the coordinates the navigator.geolocation shim reports. The
|
||||||
/// values are injected as numeric globals the bootstrap reads; when unset it
|
/// values are injected as numeric globals the bootstrap reads; when unset it
|
||||||
/// keeps the built-in default. Callers validate the range before calling.
|
/// keeps the built-in default. Callers validate the range before calling.
|
||||||
|
|||||||
@@ -23,14 +23,14 @@ tempfile = "3"
|
|||||||
# Emulation builder reshuffled). A caret requirement let a fresh resolve pull a
|
# Emulation builder reshuffled). A caret requirement let a fresh resolve pull a
|
||||||
# newer, incompatible rc and broke `cargo build --features stealth` (issue #234).
|
# newer, incompatible rc and broke `cargo build --features stealth` (issue #234).
|
||||||
# Pin exact versions so the build always resolves to the API wreq_client.rs targets.
|
# Pin exact versions so the build always resolves to the API wreq_client.rs targets.
|
||||||
wreq-util = { version = "=3.0.0-rc.10", optional = true }
|
wreq-util = { version = "=3.0.0-rc.12", optional = true }
|
||||||
|
|
||||||
# `prefix-symbols` renames BoringSSL exports to avoid clashes with system OpenSSL,
|
# `prefix-symbols` renames BoringSSL exports to avoid clashes with system OpenSSL,
|
||||||
# but the renaming is only correct on Linux and Android (per wreq's README).
|
# but the renaming is only correct on Linux and Android (per wreq's README).
|
||||||
# Enabling it on other platforms produces unresolved `build_script_main_*`
|
# Enabling it on other platforms produces unresolved `build_script_main_*`
|
||||||
# symbols at link time (see issue #39).
|
# symbols at link time (see issue #39).
|
||||||
[target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies]
|
[target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies]
|
||||||
wreq = { version = "=6.0.0-rc.28", optional = true, features = ["prefix-symbols", "socks"] }
|
wreq = { version = "=6.0.0-rc.29", optional = true, features = ["prefix-symbols", "socks"] }
|
||||||
|
|
||||||
[target.'cfg(not(any(target_os = "linux", target_os = "android")))'.dependencies]
|
[target.'cfg(not(any(target_os = "linux", target_os = "android")))'.dependencies]
|
||||||
wreq = { version = "=6.0.0-rc.28", optional = true, features = ["socks"] }
|
wreq = { version = "=6.0.0-rc.29", optional = true, features = ["socks"] }
|
||||||
@@ -36,21 +36,13 @@ impl StealthHttpClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_proxy(cookie_jar: Arc<CookieJar>, proxy_url: Option<&str>) -> Self {
|
pub fn with_proxy(cookie_jar: Arc<CookieJar>, proxy_url: Option<&str>) -> Self {
|
||||||
// Issue #184: `set_default_paths()` reads OpenSSL's compile-time CA
|
let emulation_opts = wreq_util::Emulation::builder()
|
||||||
// paths, which only resolve on Linux. On Windows the store ends up
|
.profile(wreq_util::Profile::Chrome145)
|
||||||
// empty and every TLS handshake fails with CERTIFICATE_VERIFY_FAILED.
|
.platform(wreq_util::Platform::Linux)
|
||||||
// `CertStore::default()` uses wreq's bundled Mozilla roots
|
|
||||||
// (`webpki-root-certs`), which works the same on every platform.
|
|
||||||
let cert_store = wreq::tls::CertStore::default();
|
|
||||||
|
|
||||||
let emulation_opts = wreq_util::EmulationOption::builder()
|
|
||||||
.emulation(wreq_util::Emulation::Chrome145)
|
|
||||||
.emulation_os(wreq_util::EmulationOS::Linux)
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let mut builder = wreq::Client::builder()
|
let mut builder = wreq::Client::builder()
|
||||||
.emulation(emulation_opts)
|
.emulation(emulation_opts)
|
||||||
.cert_store(cert_store)
|
|
||||||
.timeout(Duration::from_secs(30))
|
.timeout(Duration::from_secs(30))
|
||||||
.redirect(wreq::redirect::Policy::none());
|
.redirect(wreq::redirect::Policy::none());
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user