jumpy-lion 0.1.6-beta.7 → 1.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -607
- package/browser/fonts/macos-bundle/40-macos-aliases.conf +515 -0
- package/browser/fonts/macos-bundle/README.md +24 -0
- package/browser/fonts/macos-bundle/install.sh +83 -0
- package/dist/browser-controller.d.ts +47 -4
- package/dist/browser-controller.d.ts.map +1 -1
- package/dist/browser-controller.js +219 -278
- package/dist/browser-controller.js.map +1 -1
- package/dist/browser-plugin.d.ts +82 -110
- package/dist/browser-plugin.d.ts.map +1 -1
- package/dist/browser-plugin.js +376 -379
- package/dist/browser-plugin.js.map +1 -1
- package/dist/browser-process/align-fingerprint-config.d.ts +36 -0
- package/dist/browser-process/align-fingerprint-config.d.ts.map +1 -0
- package/dist/browser-process/align-fingerprint-config.js +74 -0
- package/dist/browser-process/align-fingerprint-config.js.map +1 -0
- package/dist/browser-process/anti-detect-browser.d.ts +2 -2
- package/dist/browser-process/anti-detect-browser.js +7 -7
- package/dist/browser-process/anti-detect-config.d.ts +131 -2
- package/dist/browser-process/anti-detect-config.d.ts.map +1 -1
- package/dist/browser-process/anti-detect-config.js +337 -127
- package/dist/browser-process/anti-detect-config.js.map +1 -1
- package/dist/browser-process/browser.d.ts +25 -92
- package/dist/browser-process/browser.d.ts.map +1 -1
- package/dist/browser-process/browser.js +429 -73
- package/dist/browser-process/browser.js.map +1 -1
- package/dist/browser-process/fingerprint-config.d.ts +146 -0
- package/dist/browser-process/fingerprint-config.d.ts.map +1 -0
- package/dist/browser-process/fingerprint-config.js +308 -0
- package/dist/browser-process/fingerprint-config.js.map +1 -0
- package/dist/browser-process/get-chrome-executable.d.ts +6 -0
- package/dist/browser-process/get-chrome-executable.d.ts.map +1 -1
- package/dist/browser-process/get-chrome-executable.js +79 -4
- package/dist/browser-process/get-chrome-executable.js.map +1 -1
- package/dist/browser-process/gpu-family-profiles.d.ts +58 -0
- package/dist/browser-process/gpu-family-profiles.d.ts.map +1 -0
- package/dist/browser-process/gpu-family-profiles.js +480 -0
- package/dist/browser-process/gpu-family-profiles.js.map +1 -0
- package/dist/browser-process/launch-options.d.ts +301 -0
- package/dist/browser-process/launch-options.d.ts.map +1 -0
- package/dist/browser-process/launch-options.js +2 -0
- package/dist/browser-process/launch-options.js.map +1 -0
- package/dist/browser-process/port-allocator.d.ts +64 -0
- package/dist/browser-process/port-allocator.d.ts.map +1 -0
- package/dist/browser-process/port-allocator.js +198 -0
- package/dist/browser-process/port-allocator.js.map +1 -0
- package/dist/browser-process/process.d.ts +85 -0
- package/dist/browser-process/process.d.ts.map +1 -1
- package/dist/browser-process/process.js +235 -19
- package/dist/browser-process/process.js.map +1 -1
- package/dist/browser-process/signal-cleanup.d.ts +40 -0
- package/dist/browser-process/signal-cleanup.d.ts.map +1 -0
- package/dist/browser-process/signal-cleanup.js +105 -0
- package/dist/browser-process/signal-cleanup.js.map +1 -0
- package/dist/browser-process/widevine-cdm.d.ts +144 -0
- package/dist/browser-process/widevine-cdm.d.ts.map +1 -0
- package/dist/browser-process/widevine-cdm.js +298 -0
- package/dist/browser-process/widevine-cdm.js.map +1 -0
- package/dist/browser-profiles/chrome/populate-profile.d.ts.map +1 -1
- package/dist/browser-profiles/chrome/populate-profile.js +21 -22
- package/dist/browser-profiles/chrome/populate-profile.js.map +1 -1
- package/dist/connection/cdp-reconnection.d.ts +50 -0
- package/dist/connection/cdp-reconnection.d.ts.map +1 -0
- package/dist/connection/cdp-reconnection.js +75 -0
- package/dist/connection/cdp-reconnection.js.map +1 -0
- package/dist/connection/page-session.d.ts +114 -0
- package/dist/connection/page-session.d.ts.map +1 -0
- package/dist/connection/page-session.js +237 -0
- package/dist/connection/page-session.js.map +1 -0
- package/dist/connection/session-client.d.ts +34 -0
- package/dist/connection/session-client.d.ts.map +1 -0
- package/dist/connection/session-client.js +129 -0
- package/dist/connection/session-client.js.map +1 -0
- package/dist/crawler.d.ts +9 -88
- package/dist/crawler.d.ts.map +1 -1
- package/dist/crawler.js +157 -8
- package/dist/crawler.js.map +1 -1
- package/dist/fingerprinting/fingerprint-injector.d.ts +24 -114
- package/dist/fingerprinting/fingerprint-injector.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-injector.js +305 -611
- package/dist/fingerprinting/fingerprint-injector.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.d.ts +1 -1
- package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.js +16 -14
- package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/index.d.ts +6 -2
- package/dist/fingerprinting/fingerprint-overrides/index.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/index.js +6 -2
- package/dist/fingerprinting/fingerprint-overrides/index.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/keyboard-humanization.d.ts +1 -1
- package/dist/fingerprinting/fingerprint-overrides/keyboard-humanization.js +4 -4
- package/dist/fingerprinting/fingerprint-overrides/keyboard-humanization.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.js +4 -4
- package/dist/fingerprinting/fingerprint-overrides/navigator-override.d.ts +18 -0
- package/dist/fingerprinting/fingerprint-overrides/navigator-override.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/navigator-override.js +136 -0
- package/dist/fingerprinting/fingerprint-overrides/navigator-override.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/override.d.ts +151 -0
- package/dist/fingerprinting/fingerprint-overrides/override.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/override.js +14 -0
- package/dist/fingerprinting/fingerprint-overrides/override.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.js +46 -15
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/registry.d.ts +43 -0
- package/dist/fingerprinting/fingerprint-overrides/registry.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/registry.js +342 -0
- package/dist/fingerprinting/fingerprint-overrides/registry.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/screen-override.d.ts +16 -0
- package/dist/fingerprinting/fingerprint-overrides/screen-override.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/screen-override.js +175 -0
- package/dist/fingerprinting/fingerprint-overrides/screen-override.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/scroll-humanization.d.ts +1 -1
- package/dist/fingerprinting/fingerprint-overrides/scroll-humanization.js +4 -4
- package/dist/fingerprinting/fingerprint-overrides/scroll-humanization.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.js +75 -9
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.d.ts +1 -1
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.js +34 -20
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.js +25 -6
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/webrtc-spoofing.js +1 -1
- package/dist/fingerprinting/hardware-realism.d.ts +83 -0
- package/dist/fingerprinting/hardware-realism.d.ts.map +1 -0
- package/dist/fingerprinting/hardware-realism.js +156 -0
- package/dist/fingerprinting/hardware-realism.js.map +1 -0
- package/dist/fingerprinting/injection-planner.d.ts +133 -0
- package/dist/fingerprinting/injection-planner.d.ts.map +1 -0
- package/dist/fingerprinting/injection-planner.js +497 -0
- package/dist/fingerprinting/injection-planner.js.map +1 -0
- package/dist/fingerprinting/locale-resolver.d.ts +8 -1
- package/dist/fingerprinting/locale-resolver.d.ts.map +1 -1
- package/dist/fingerprinting/locale-resolver.js +26 -3
- package/dist/fingerprinting/locale-resolver.js.map +1 -1
- package/dist/fingerprinting/non-apify-fingerprint-generator.d.ts +4 -4
- package/dist/fingerprinting/non-apify-fingerprint-generator.d.ts.map +1 -1
- package/dist/fingerprinting/non-apify-fingerprint-generator.js +24 -58
- package/dist/fingerprinting/non-apify-fingerprint-generator.js.map +1 -1
- package/dist/fingerprinting/non-apify-profiles.json +10515 -8494
- package/dist/fingerprinting/os-consistency.d.ts +28 -0
- package/dist/fingerprinting/os-consistency.d.ts.map +1 -0
- package/dist/fingerprinting/os-consistency.js +45 -0
- package/dist/fingerprinting/os-consistency.js.map +1 -0
- package/dist/fingerprinting/profile-quality.d.ts +25 -0
- package/dist/fingerprinting/profile-quality.d.ts.map +1 -0
- package/dist/fingerprinting/profile-quality.js +310 -0
- package/dist/fingerprinting/profile-quality.js.map +1 -0
- package/dist/fingerprinting/profile-selector.d.ts +102 -0
- package/dist/fingerprinting/profile-selector.d.ts.map +1 -0
- package/dist/fingerprinting/profile-selector.js +168 -0
- package/dist/fingerprinting/profile-selector.js.map +1 -0
- package/dist/fingerprinting/ua-alignment.d.ts +83 -0
- package/dist/fingerprinting/ua-alignment.d.ts.map +1 -0
- package/dist/fingerprinting/ua-alignment.js +197 -0
- package/dist/fingerprinting/ua-alignment.js.map +1 -0
- package/dist/fingerprinting/ua-ch-brands.d.ts +88 -0
- package/dist/fingerprinting/ua-ch-brands.d.ts.map +1 -0
- package/dist/fingerprinting/ua-ch-brands.js +174 -0
- package/dist/fingerprinting/ua-ch-brands.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/input/dropdown-selector.d.ts +90 -0
- package/dist/input/dropdown-selector.d.ts.map +1 -0
- package/dist/input/dropdown-selector.js +394 -0
- package/dist/input/dropdown-selector.js.map +1 -0
- package/dist/input/element-target.d.ts +152 -0
- package/dist/input/element-target.d.ts.map +1 -0
- package/dist/input/element-target.js +461 -0
- package/dist/input/element-target.js.map +1 -0
- package/dist/input/input-emulator.d.ts +85 -0
- package/dist/input/input-emulator.d.ts.map +1 -0
- package/dist/input/input-emulator.js +325 -0
- package/dist/input/input-emulator.js.map +1 -0
- package/dist/input/input-transport.d.ts +60 -0
- package/dist/input/input-transport.d.ts.map +1 -0
- package/dist/input/input-transport.js +28 -0
- package/dist/input/input-transport.js.map +1 -0
- package/dist/input/recording-transport.d.ts +32 -0
- package/dist/input/recording-transport.d.ts.map +1 -0
- package/dist/input/recording-transport.js +43 -0
- package/dist/input/recording-transport.js.map +1 -0
- package/dist/keyboard-layout.d.ts +2 -2
- package/dist/keyboard-layout.js +2 -2
- package/dist/navigation/page-navigation.d.ts +67 -0
- package/dist/navigation/page-navigation.d.ts.map +1 -0
- package/dist/navigation/page-navigation.js +122 -0
- package/dist/navigation/page-navigation.js.map +1 -0
- package/dist/network/network-watch.d.ts +110 -0
- package/dist/network/network-watch.d.ts.map +1 -0
- package/dist/network/network-watch.js +223 -0
- package/dist/network/network-watch.js.map +1 -0
- package/dist/page.d.ts +118 -104
- package/dist/page.d.ts.map +1 -1
- package/dist/page.js +311 -1130
- package/dist/page.js.map +1 -1
- package/dist/session/inject-hook.d.ts +24 -0
- package/dist/session/inject-hook.d.ts.map +1 -0
- package/dist/session/inject-hook.js +80 -0
- package/dist/session/inject-hook.js.map +1 -0
- package/dist/session/save.d.ts +21 -0
- package/dist/session/save.d.ts.map +1 -0
- package/dist/session/save.js +163 -0
- package/dist/session/save.js.map +1 -0
- package/dist/session/tar-data-dir.d.ts +18 -0
- package/dist/session/tar-data-dir.d.ts.map +1 -0
- package/dist/session/tar-data-dir.js +105 -0
- package/dist/session/tar-data-dir.js.map +1 -0
- package/dist/session/types.d.ts +80 -0
- package/dist/session/types.d.ts.map +1 -0
- package/dist/session/types.js +29 -0
- package/dist/session/types.js.map +1 -0
- package/dist/session-profile.d.ts +102 -0
- package/dist/session-profile.d.ts.map +1 -0
- package/dist/session-profile.js +163 -0
- package/dist/session-profile.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +17 -6
- package/scripts/postinstall.cjs +58 -0
- package/dist/fingerprinting/custom-fingerprint-injector.d.ts +0 -87
- package/dist/fingerprinting/custom-fingerprint-injector.d.ts.map +0 -1
- package/dist/fingerprinting/custom-fingerprint-injector.js +0 -342
- package/dist/fingerprinting/custom-fingerprint-injector.js.map +0 -1
- package/dist/launcher-wrap.d.ts +0 -10
- package/dist/launcher-wrap.d.ts.map +0 -1
- package/dist/launcher-wrap.js +0 -11
- package/dist/launcher-wrap.js.map +0 -1
|
@@ -214,7 +214,7 @@ export const createStealthScript = () => {
|
|
|
214
214
|
Object.defineProperty(arr, 'item', { value: (index) => arr[index] || null, writable: false, enumerable: false });
|
|
215
215
|
Object.defineProperty(arr, 'namedItem', { value: (name) => arr[name] || null, writable: false, enumerable: false });
|
|
216
216
|
Object.defineProperty(arr, 'refresh', { value: () => {}, writable: false, enumerable: false });
|
|
217
|
-
// Allow for...of iteration
|
|
217
|
+
// Allow for...of iteration - checked by DataDome and FingerprintJS Pro
|
|
218
218
|
arr[Symbol.iterator] = function* () { for (let i = 0; i < fakePlugins.length; i++) yield arr[i]; };
|
|
219
219
|
return arr;
|
|
220
220
|
};
|
|
@@ -648,7 +648,7 @@ export const createStealthScript = () => {
|
|
|
648
648
|
if (originalGetGamepads) {
|
|
649
649
|
navigator.getGamepads = function() {
|
|
650
650
|
// Real Chrome returns GamepadList with 4 null slots when no gamepads
|
|
651
|
-
// connected
|
|
651
|
+
// connected - NOT an empty array. [] vs [null,null,null,null] is a
|
|
652
652
|
// checked difference between headed Chrome and headless/Chromium.
|
|
653
653
|
return [null, null, null, null];
|
|
654
654
|
};
|
|
@@ -954,11 +954,50 @@ export const createStealthScript = () => {
|
|
|
954
954
|
// meaning Cloudflare / Akamai / PerimeterX saw raw headless values. Move them
|
|
955
955
|
// here so all crawls benefit.
|
|
956
956
|
const spoofDocumentVisibility = () => {
|
|
957
|
+
// Capture the real (browser-native) accessors before any instance-level
|
|
958
|
+
// override, so we can (1) detect spurious visibilitychange events that
|
|
959
|
+
// fire without an underlying state transition (typical of CDP-driven
|
|
960
|
+
// lifecycle commands - these would expose automation if they reached
|
|
961
|
+
// the page), and (2) during real OS-driven transitions, briefly yield
|
|
962
|
+
// to the real accessors so a page's visibilitychange listener sees a
|
|
963
|
+
// visibilityState consistent with the event it just received (which
|
|
964
|
+
// is what happens on real Chrome).
|
|
965
|
+
let _origVisibilityGet = null;
|
|
966
|
+
let _origHiddenGet = null;
|
|
957
967
|
try {
|
|
958
|
-
Object.
|
|
959
|
-
Object.
|
|
968
|
+
const _vDesc = Object.getOwnPropertyDescriptor(Document.prototype, 'visibilityState');
|
|
969
|
+
const _hDesc = Object.getOwnPropertyDescriptor(Document.prototype, 'hidden');
|
|
970
|
+
if (_vDesc && _vDesc.get) _origVisibilityGet = _vDesc.get;
|
|
971
|
+
if (_hDesc && _hDesc.get) _origHiddenGet = _hDesc.get;
|
|
960
972
|
} catch (e) {}
|
|
961
973
|
|
|
974
|
+
const installSpoof = () => {
|
|
975
|
+
try {
|
|
976
|
+
Object.defineProperty(document, 'hidden',
|
|
977
|
+
{ get: () => false, configurable: true });
|
|
978
|
+
Object.defineProperty(document, 'visibilityState',
|
|
979
|
+
{ get: () => 'visible', configurable: true });
|
|
980
|
+
} catch (e) {}
|
|
981
|
+
};
|
|
982
|
+
const restoreReal = () => {
|
|
983
|
+
try {
|
|
984
|
+
Object.defineProperty(document, 'hidden', {
|
|
985
|
+
get: function() {
|
|
986
|
+
return _origHiddenGet ? _origHiddenGet.call(this) : false;
|
|
987
|
+
},
|
|
988
|
+
configurable: true
|
|
989
|
+
});
|
|
990
|
+
Object.defineProperty(document, 'visibilityState', {
|
|
991
|
+
get: function() {
|
|
992
|
+
return _origVisibilityGet ? _origVisibilityGet.call(this) : 'visible';
|
|
993
|
+
},
|
|
994
|
+
configurable: true
|
|
995
|
+
});
|
|
996
|
+
} catch (e) {}
|
|
997
|
+
};
|
|
998
|
+
|
|
999
|
+
installSpoof();
|
|
1000
|
+
|
|
962
1001
|
document.hasFocus = function() { return true; };
|
|
963
1002
|
try {
|
|
964
1003
|
Object.defineProperty(document.hasFocus, 'toString', {
|
|
@@ -967,12 +1006,39 @@ export const createStealthScript = () => {
|
|
|
967
1006
|
});
|
|
968
1007
|
} catch (e) {}
|
|
969
1008
|
|
|
970
|
-
|
|
1009
|
+
let _lastReal = _origVisibilityGet ? _origVisibilityGet.call(document) : 'visible';
|
|
1010
|
+
let _restoring = false;
|
|
1011
|
+
|
|
971
1012
|
const origAEL = document.addEventListener.bind(document);
|
|
972
|
-
const
|
|
973
|
-
if (e.type
|
|
1013
|
+
const _visibilityHandler = (e) => {
|
|
1014
|
+
if (e.type !== 'visibilitychange') return;
|
|
1015
|
+
if (!_origVisibilityGet) return;
|
|
1016
|
+
const real = _origVisibilityGet.call(document);
|
|
1017
|
+
if (real === _lastReal) {
|
|
1018
|
+
// Spurious dispatch (e.g. CDP-driven). Suppress so it cannot
|
|
1019
|
+
// betray automation through an event-without-state-change.
|
|
1020
|
+
e.stopImmediatePropagation();
|
|
1021
|
+
return;
|
|
1022
|
+
}
|
|
1023
|
+
_lastReal = real;
|
|
1024
|
+
|
|
1025
|
+
// Genuine OS-driven transition (macOS Space switch, minimize,
|
|
1026
|
+
// fullscreen toggle, etc.). Let the event propagate so the page's
|
|
1027
|
+
// render loop / animation timers can resume, but yield to the
|
|
1028
|
+
// real accessors for the duration of the synchronous dispatch so
|
|
1029
|
+
// listeners read a state consistent with the event. The spoof is
|
|
1030
|
+
// re-installed in the next microtask, after sync listeners have
|
|
1031
|
+
// finished running.
|
|
1032
|
+
if (!_restoring) {
|
|
1033
|
+
_restoring = true;
|
|
1034
|
+
restoreReal();
|
|
1035
|
+
Promise.resolve().then(() => {
|
|
1036
|
+
installSpoof();
|
|
1037
|
+
_restoring = false;
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
974
1040
|
};
|
|
975
|
-
origAEL('visibilitychange',
|
|
1041
|
+
origAEL('visibilitychange', _visibilityHandler, true);
|
|
976
1042
|
};
|
|
977
1043
|
|
|
978
1044
|
// 31. Encrypted Media Extensions (Widevine) Spoofing
|
|
@@ -1101,7 +1167,7 @@ export const createStealthScript = () => {
|
|
|
1101
1167
|
applyProtection('Worker Constructor Protection', protectWorkerConstructor);
|
|
1102
1168
|
applyProtection('SharedWorker Protection', protectSharedWorkerConstructor);
|
|
1103
1169
|
applyProtection('PostMessage Protection', protectPostMessage);
|
|
1104
|
-
// Chrome authenticity patches
|
|
1170
|
+
// Chrome authenticity patches - make Chromium look like real Chrome
|
|
1105
1171
|
applyProtection('Document Visibility Spoofing', spoofDocumentVisibility);
|
|
1106
1172
|
applyProtection('EME/Widevine Spoofing', spoofEME);
|
|
1107
1173
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stealth-script.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/stealth-script.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAW,EAAE;IAC5C,OAAO
|
|
1
|
+
{"version":3,"file":"stealth-script.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/stealth-script.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAW,EAAE;IAC5C,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA6oCL,CAAC;AACP,CAAC,CAAC"}
|
|
@@ -23,5 +23,5 @@ export interface UAClientHintsData {
|
|
|
23
23
|
uaFullVersion?: string;
|
|
24
24
|
wow64?: boolean;
|
|
25
25
|
}
|
|
26
|
-
export declare const createUAClientHintsSpoofingScript: (platform?: string, generatedUAData?: UAClientHintsData) => string;
|
|
26
|
+
export declare const createUAClientHintsSpoofingScript: (platform?: string, generatedUAData?: UAClientHintsData, binaryFullVersion?: string) => string;
|
|
27
27
|
//# sourceMappingURL=ua-ch.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ua-ch.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/ua-ch.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"ua-ch.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/ua-ch.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,MAAM,WAAW,iBAAiB;IAC9B,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC9C,eAAe,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACvD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,iCAAiC,wCAExB,iBAAiB,sBACf,MAAM,KAC3B,MAmOF,CAAC"}
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
* to ensure UA-CH brands/versions match the generated userAgent string.
|
|
6
6
|
* When not provided, falls back to hardcoded defaults.
|
|
7
7
|
*/
|
|
8
|
-
|
|
8
|
+
import { resolvePlatformVersion } from '../hardware-realism.js';
|
|
9
|
+
import { brandListScriptExpression } from '../ua-ch-brands.js';
|
|
10
|
+
export const createUAClientHintsSpoofingScript = (platform = 'Win32', generatedUAData, binaryFullVersion) => {
|
|
9
11
|
// When generated data is available, use it directly for consistency
|
|
10
12
|
// with the generated userAgent string. Otherwise use defaults.
|
|
11
13
|
let platformData;
|
|
@@ -13,30 +15,34 @@ export const createUAClientHintsSpoofingScript = (platform = 'Win32', generatedU
|
|
|
13
15
|
let architecture;
|
|
14
16
|
let bitness;
|
|
15
17
|
let wow64;
|
|
18
|
+
// platformVersion comes from hardware-realism.ts rather than a literal, so the
|
|
19
|
+
// no-profile path cannot advertise a stale macOS release or a kernel version
|
|
20
|
+
// on Linux (real Chrome sends an empty string there) - see issue #137. Index 0
|
|
21
|
+
// is the most common value for the platform.
|
|
16
22
|
if (generatedUAData) {
|
|
17
23
|
platformData = generatedUAData.platform || 'Windows';
|
|
18
|
-
platformVersion = generatedUAData.platformVersion
|
|
24
|
+
platformVersion = generatedUAData.platformVersion ?? resolvePlatformVersion(platform, 0);
|
|
19
25
|
architecture = generatedUAData.architecture || 'x86';
|
|
20
26
|
bitness = generatedUAData.bitness || '64';
|
|
21
27
|
wow64 = generatedUAData.wow64 ?? false;
|
|
22
28
|
}
|
|
23
29
|
else if (platform.startsWith('Win') || platform === 'Win32') {
|
|
24
30
|
platformData = 'Windows';
|
|
25
|
-
platformVersion = '
|
|
31
|
+
platformVersion = resolvePlatformVersion('Win32', 0);
|
|
26
32
|
architecture = 'x86';
|
|
27
33
|
bitness = '64';
|
|
28
34
|
wow64 = false;
|
|
29
35
|
}
|
|
30
36
|
else if (platform.startsWith('Mac')) {
|
|
31
37
|
platformData = 'macOS';
|
|
32
|
-
platformVersion = '
|
|
38
|
+
platformVersion = resolvePlatformVersion('MacIntel', 0);
|
|
33
39
|
architecture = 'arm';
|
|
34
40
|
bitness = '64';
|
|
35
41
|
wow64 = false;
|
|
36
42
|
}
|
|
37
43
|
else {
|
|
38
44
|
platformData = 'Linux';
|
|
39
|
-
platformVersion = '
|
|
45
|
+
platformVersion = resolvePlatformVersion('Linux x86_64', 0);
|
|
40
46
|
architecture = 'x86';
|
|
41
47
|
bitness = '64';
|
|
42
48
|
wow64 = false;
|
|
@@ -45,8 +51,15 @@ export const createUAClientHintsSpoofingScript = (platform = 'Win32', generatedU
|
|
|
45
51
|
// When no generated data, we parse the version from navigator.userAgent at runtime
|
|
46
52
|
// to ensure JS-side brands match the HTTP-level Sec-CH-UA headers set by
|
|
47
53
|
// Network.setUserAgentOverride (which also parses from the UA string).
|
|
48
|
-
|
|
49
|
-
|
|
54
|
+
// UA-CH keeps the REAL build version even though UA Reduction froze the UA
|
|
55
|
+
// string to MAJOR.0.0.0 - real Chrome 147 reports 147.0.7727.56 in
|
|
56
|
+
// uaFullVersion / fullVersionList. Parsing the version out of
|
|
57
|
+
// navigator.userAgent (the old fallback) therefore reported 147.0.0.0, a
|
|
58
|
+
// shape no Chrome emits and one that gets every high-entropy request
|
|
59
|
+
// refused (issue #131). Prefer the profile's build, then the binary's own.
|
|
60
|
+
const resolvedFullVersion = generatedUAData?.uaFullVersion || binaryFullVersion || '';
|
|
61
|
+
const hasGeneratedVersion = !!resolvedFullVersion;
|
|
62
|
+
const fullVersion = resolvedFullVersion;
|
|
50
63
|
// Brands - use generated data if available
|
|
51
64
|
const brandsJson = generatedUAData?.brands
|
|
52
65
|
? JSON.stringify(generatedUAData.brands)
|
|
@@ -66,24 +79,25 @@ export const createUAClientHintsSpoofingScript = (platform = 'Win32', generatedU
|
|
|
66
79
|
// Parse Chrome version from UA at runtime to stay in sync with
|
|
67
80
|
// HTTP-level Sec-CH-UA set by Network.setUserAgentOverride.
|
|
68
81
|
const _parsedMatch = navigator.userAgent.match(/Chrome\\/([\\d.]+)/);
|
|
69
|
-
const
|
|
70
|
-
const _rtMajorVersion =
|
|
82
|
+
const _rtUaVersion = _parsedMatch ? _parsedMatch[1] : '134.0.6998.88';
|
|
83
|
+
const _rtMajorVersion = _rtUaVersion.split('.')[0];
|
|
84
|
+
// UA Reduction zeroes minor/build/patch in the UA string only; UA-CH keeps
|
|
85
|
+
// the real build. Never derive the full version from the UA - a
|
|
86
|
+
// "147.0.0.0" full-version list is refused by origins that request
|
|
87
|
+
// high-entropy hints (issue #131).
|
|
88
|
+
const _rtFullVersion = ${hasGeneratedVersion ? `"${resolvedFullVersion}"` : '_rtUaVersion'};
|
|
71
89
|
|
|
72
|
-
// Brand list - from generated fingerprint or derived from UA at runtime
|
|
90
|
+
// Brand list - from generated fingerprint or derived from UA at runtime.
|
|
91
|
+
// The runtime path derives the GREASE token and the list order from the
|
|
92
|
+
// major the way Chromium does (see ua-ch-brands.ts): a hardcoded
|
|
93
|
+
// "Not_A Brand";v="24" would contradict any major but 131 - the exact
|
|
94
|
+
// mismatch Naver answers with a challenge-free 418 (issue #131).
|
|
73
95
|
const brands = Object.freeze(
|
|
74
|
-
${brandsJson ||
|
|
75
|
-
{ brand: "Google Chrome", version: _rtMajorVersion },
|
|
76
|
-
{ brand: "Chromium", version: _rtMajorVersion },
|
|
77
|
-
{ brand: "Not_A Brand", version: "24" },
|
|
78
|
-
]`}.map(b => Object.freeze(b))
|
|
96
|
+
${brandsJson || brandListScriptExpression('_rtMajorVersion', '_rtMajorVersion', 'major')}.map(b => Object.freeze(b))
|
|
79
97
|
);
|
|
80
98
|
|
|
81
99
|
const fullVersionList = Object.freeze(
|
|
82
|
-
${fullVersionListJson ||
|
|
83
|
-
{ brand: "Google Chrome", version: _rtFullVersion },
|
|
84
|
-
{ brand: "Chromium", version: _rtFullVersion },
|
|
85
|
-
{ brand: "Not_A Brand", version: "24.0.0.0" },
|
|
86
|
-
]`}.map(b => Object.freeze(b))
|
|
100
|
+
${fullVersionListJson || brandListScriptExpression('_rtMajorVersion', '_rtFullVersion', 'full')}.map(b => Object.freeze(b))
|
|
87
101
|
);
|
|
88
102
|
|
|
89
103
|
const mobile = false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ua-ch.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/ua-ch.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"ua-ch.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/ua-ch.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webgl-spoofing.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/webgl-spoofing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,WAAW;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,eAAO,MAAM,yBAAyB,sBAAuB,WAAW,KAAG,
|
|
1
|
+
{"version":3,"file":"webgl-spoofing.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/webgl-spoofing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,WAAW;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,eAAO,MAAM,yBAAyB,sBAAuB,WAAW,KAAG,MA2R1E,CAAC"}
|
|
@@ -56,16 +56,35 @@ export const createWebGLSpoofingScript = (fingerprintWebGL) => {
|
|
|
56
56
|
],
|
|
57
57
|
},
|
|
58
58
|
'MacIntel': {
|
|
59
|
-
|
|
59
|
+
// Modern Mac population is overwhelmingly Apple Silicon. Intel and
|
|
60
|
+
// AMD discrete-GPU Macs (2018-2020) are rare in 2026; including them
|
|
61
|
+
// creates a much wider hash distribution than reality and the
|
|
62
|
+
// discrete-GPU strings imply Metal hardware that can't match the
|
|
63
|
+
// SwiftShader-rendered pixels we actually produce. Pin to Apple
|
|
64
|
+
// Silicon variants so the spoofed renderer string and the actual
|
|
65
|
+
// rendering backend stay closer aligned.
|
|
66
|
+
vendors: ['Google Inc. (Apple)'],
|
|
60
67
|
renderers: [
|
|
68
|
+
'ANGLE (Apple, Apple M1, OpenGL 4.1)',
|
|
61
69
|
'ANGLE (Apple, Apple M1 Pro, OpenGL 4.1)',
|
|
70
|
+
'ANGLE (Apple, Apple M1 Max, OpenGL 4.1)',
|
|
62
71
|
'ANGLE (Apple, Apple M2, OpenGL 4.1)',
|
|
63
|
-
'ANGLE (
|
|
64
|
-
'ANGLE (
|
|
72
|
+
'ANGLE (Apple, Apple M2 Pro, OpenGL 4.1)',
|
|
73
|
+
'ANGLE (Apple, Apple M2 Max, OpenGL 4.1)',
|
|
74
|
+
'ANGLE (Apple, Apple M3, OpenGL 4.1)',
|
|
75
|
+
'ANGLE (Apple, Apple M3 Pro, OpenGL 4.1)',
|
|
76
|
+
'ANGLE (Apple, Apple M3 Max, OpenGL 4.1)',
|
|
77
|
+
'ANGLE (Apple, Apple M4, OpenGL 4.1)',
|
|
78
|
+
'ANGLE (Apple, Apple M4 Pro, OpenGL 4.1)',
|
|
65
79
|
],
|
|
66
80
|
vendorPairs: [
|
|
81
|
+
{ vendor: 'Google Inc. (Apple)', renderer: 'ANGLE (Apple, Apple M1, OpenGL 4.1)' },
|
|
67
82
|
{ vendor: 'Google Inc. (Apple)', renderer: 'ANGLE (Apple, Apple M1 Pro, OpenGL 4.1)' },
|
|
68
|
-
{ vendor: 'Google Inc. (
|
|
83
|
+
{ vendor: 'Google Inc. (Apple)', renderer: 'ANGLE (Apple, Apple M2, OpenGL 4.1)' },
|
|
84
|
+
{ vendor: 'Google Inc. (Apple)', renderer: 'ANGLE (Apple, Apple M2 Pro, OpenGL 4.1)' },
|
|
85
|
+
{ vendor: 'Google Inc. (Apple)', renderer: 'ANGLE (Apple, Apple M3, OpenGL 4.1)' },
|
|
86
|
+
{ vendor: 'Google Inc. (Apple)', renderer: 'ANGLE (Apple, Apple M3 Pro, OpenGL 4.1)' },
|
|
87
|
+
{ vendor: 'Google Inc. (Apple)', renderer: 'ANGLE (Apple, Apple M4, OpenGL 4.1)' },
|
|
69
88
|
],
|
|
70
89
|
},
|
|
71
90
|
'Linux x86_64': {
|
|
@@ -162,7 +181,7 @@ export const createWebGLSpoofingScript = (fingerprintWebGL) => {
|
|
|
162
181
|
// Override getShaderPrecisionFormat to prevent GPU cross-referencing.
|
|
163
182
|
// Anti-bot scripts can compare precision values against the claimed GPU/platform.
|
|
164
183
|
// These values match the standard IEEE 754 precision formats reported by modern
|
|
165
|
-
// D3D11/Metal/Vulkan drivers
|
|
184
|
+
// D3D11/Metal/Vulkan drivers - consistent across NVIDIA, AMD, and Intel GPUs.
|
|
166
185
|
const _shaderPrecision = {
|
|
167
186
|
35633: { // VERTEX_SHADER
|
|
168
187
|
36336: { rangeMin: 1, rangeMax: 1, precision: 8 }, // LOW_FLOAT
|
|
@@ -187,7 +206,7 @@ export const createWebGLSpoofingScript = (fingerprintWebGL) => {
|
|
|
187
206
|
const fmt = shaderFmts && shaderFmts[precisionType];
|
|
188
207
|
if (fmt) {
|
|
189
208
|
// Return a plain object that mirrors WebGLShaderPrecisionFormat fields.
|
|
190
|
-
// Anti-bot scripts read .rangeMin/.rangeMax/.precision
|
|
209
|
+
// Anti-bot scripts read .rangeMin/.rangeMax/.precision - instanceof is not checked.
|
|
191
210
|
return { rangeMin: fmt.rangeMin, rangeMax: fmt.rangeMax, precision: fmt.precision };
|
|
192
211
|
}
|
|
193
212
|
return _origGetShaderPrecisionFormat.apply(this, arguments);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webgl-spoofing.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/webgl-spoofing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,gBAA8B,EAAU,EAAE;IAChF,iFAAiF;IACjF,MAAM,cAAc,GAAG,gBAAgB,IAAI,CAAC,gBAAgB,CAAC,cAAc,IAAI,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;IAElH,OAAO;;;;;;;;;;UAUD,cAAc,CAAC,CAAC,CAAC;;oCAES,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC;;;;SAI3D,CAAC,CAAC,CAAC
|
|
1
|
+
{"version":3,"file":"webgl-spoofing.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/webgl-spoofing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,gBAA8B,EAAU,EAAE;IAChF,iFAAiF;IACjF,MAAM,cAAc,GAAG,gBAAgB,IAAI,CAAC,gBAAgB,CAAC,cAAc,IAAI,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;IAElH,OAAO;;;;;;;;;;UAUD,cAAc,CAAC,CAAC,CAAC;;oCAES,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC;;;;SAI3D,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SA0GH;;;;;;;;;;;;;;;;;;;yBAmBgB,cAAc,IAAI,gBAAgB,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,UAAU;;;yBAGxF,cAAc,IAAI,gBAAgB,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,gBAAgB,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAgFjH,CAAC,cAAc,CAAC,CAAC,CAAC;;;;;;;;;SASnB,CAAC,CAAC,CAAC;;SAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA2CH,CAAC;AACP,CAAC,CAAC"}
|
|
@@ -60,7 +60,7 @@ export const createWebRTCSpoofingScript = () => {
|
|
|
60
60
|
if (!candidateStr) return candidateStr;
|
|
61
61
|
// Match private/local IPs (10.x, 172.16-31.x, 192.168.x, fd00::/8, fe80::/10)
|
|
62
62
|
return candidateStr
|
|
63
|
-
.replace(/(?:(?:10|127)
|
|
63
|
+
.replace(/(?:(?:10|127)\\.\\d{1,3}|192\\.168|172\\.(?:1[6-9]|2\\d|3[01]))(?:\\.\\d{1,3}){2}/g, '0.0.0.0')
|
|
64
64
|
.replace(/[0-9a-f]{1,4}(?::[0-9a-f]{1,4}){7}/gi, (match) => {
|
|
65
65
|
if (match.startsWith('fd') || match.startsWith('fe80')) return '0.0.0.0';
|
|
66
66
|
return match;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hardware- and OS-realism helpers shared by BOTH injection paths.
|
|
3
|
+
*
|
|
4
|
+
* The native (C++ FingerprintConfig) path and the JS-injection path each used
|
|
5
|
+
* to carry their own copy of these decisions, and they disagreed - which is how
|
|
6
|
+
* issue #137 happened:
|
|
7
|
+
*
|
|
8
|
+
* - The native path fell back to a macOS platform version on LINUX profiles,
|
|
9
|
+
* because 90% of the harvested Linux pool rows carry no platform version and
|
|
10
|
+
* the fallback was a bare "15.0.0". A Linux Chrome reporting a Sequoia
|
|
11
|
+
* version is a contradiction on its own, and the JS path meanwhile used
|
|
12
|
+
* kernel-shaped values for Linux, so the two paths also disagreed with each
|
|
13
|
+
* other.
|
|
14
|
+
* - The native path resampled the pool's implausible `deviceMemory` values
|
|
15
|
+
* (0 / 1 / 2 / 4 GB on machines that have never shipped with less than 8);
|
|
16
|
+
* the JS path baked the raw value into the page, and because `0` is falsy it
|
|
17
|
+
* skipped the override entirely and leaked the HOST's real RAM.
|
|
18
|
+
* - The storage quota was derived from the RAW pool memory while the page
|
|
19
|
+
* reported the resampled value, so a session could claim 32 GB of RAM with a
|
|
20
|
+
* 1 GB machine's disk quota.
|
|
21
|
+
*
|
|
22
|
+
* Everything here is a pure function of (seed, input), so both paths produce the
|
|
23
|
+
* same values for the same session and the whole surface stays coherent.
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* UA-CH `platformVersion` candidates per `navigator.platform`.
|
|
27
|
+
*
|
|
28
|
+
* - **Linux** is the empty string. Chromium's `GetPlatformVersion()`
|
|
29
|
+
* (components/embedder_support/user_agent_utils.cc) returns `std::string()` on
|
|
30
|
+
* Linux once the platform-version reduction is enabled, and the harvested pool
|
|
31
|
+
* corroborates it: 90% of real Linux rows carry no platform version at all.
|
|
32
|
+
* Never a version number here, and never a macOS one.
|
|
33
|
+
* - **macOS** is Tahoe-era. Measured on a real macOS host running Chrome 150:
|
|
34
|
+
* `sec-ch-ua-platform-version: "26.3.0"`. The pool agrees, with 57% of mac
|
|
35
|
+
* rows on 26.x. Repeats weight the distribution toward the current release.
|
|
36
|
+
* - **Windows** keeps the UA-CH reduced mapping, which is overwhelmingly 15.0.0
|
|
37
|
+
* for Windows 11 with a small tail at 14.0.0.
|
|
38
|
+
*/
|
|
39
|
+
export declare const PLATFORM_VERSION_CANDIDATES: Readonly<Record<string, readonly string[]>>;
|
|
40
|
+
/**
|
|
41
|
+
* Resolve the UA-CH `platformVersion` for a platform, deterministically per
|
|
42
|
+
* seed. Both injection paths call this, so the JS override, the native config
|
|
43
|
+
* and the `sec-ch-ua-platform-version` header cannot disagree.
|
|
44
|
+
*/
|
|
45
|
+
export declare function resolvePlatformVersion(platform: string | undefined, seed: number): string;
|
|
46
|
+
/**
|
|
47
|
+
* Pick a `navigator.deviceMemory` that a real machine of this class would
|
|
48
|
+
* report. Plausible upstream values pass through untouched; the pool's legacy
|
|
49
|
+
* spec-bucketed values (≤ 8 GB, including 0) are resampled from
|
|
50
|
+
* `MEMORY_DISTRIBUTION`.
|
|
51
|
+
*
|
|
52
|
+
* Guaranteed to return at least 8, so no caller can end up with a falsy value -
|
|
53
|
+
* that is what silently disabled the JS-path override and leaked the host's RAM.
|
|
54
|
+
*/
|
|
55
|
+
export declare function deriveRealisticDeviceMemory(seed: number, rawFromFingerprint: number | undefined): number;
|
|
56
|
+
/**
|
|
57
|
+
* `navigator.storage.estimate().quota`, pinned per session so the host's real
|
|
58
|
+
* disk never leaks and so the same profile reports the same quota on every host.
|
|
59
|
+
*
|
|
60
|
+
* MUST be called with the memory value we actually report, not the raw pool
|
|
61
|
+
* value - the point is coherence between the two. Chrome's StorageManager
|
|
62
|
+
* reports roughly 60% of total disk space; the ±10% seed-driven jitter keeps
|
|
63
|
+
* different sessions from sharing one quota.
|
|
64
|
+
*/
|
|
65
|
+
export declare function deriveStorageQuota(seed: number, deviceMemoryGB: number): number;
|
|
66
|
+
/**
|
|
67
|
+
* Stable non-negative hash of a session key, for paths that hold a seed STRING
|
|
68
|
+
* (the JS injector's proxy session key) rather than the numeric seed the native
|
|
69
|
+
* config generator computes. Math-only so the no-bitwise lint rule stays happy.
|
|
70
|
+
*/
|
|
71
|
+
export declare function stableSeedFromString(key: string): number;
|
|
72
|
+
/**
|
|
73
|
+
* The platform version to advertise for a profile: the profile's own value when
|
|
74
|
+
* it has a usable one, otherwise a seeded candidate - except on Linux, where the
|
|
75
|
+
* answer is always the empty string.
|
|
76
|
+
*
|
|
77
|
+
* Linux is unconditional because the profile cannot be trusted there: 10% of the
|
|
78
|
+
* harvested Linux rows carry a kernel-shaped version (6.x) from before Chrome
|
|
79
|
+
* reduced the Linux platform version, and advertising one today announces a
|
|
80
|
+
* value current Chrome never sends.
|
|
81
|
+
*/
|
|
82
|
+
export declare function normalizePlatformVersion(platform: string | undefined, profileValue: string | undefined, seed: number): string;
|
|
83
|
+
//# sourceMappingURL=hardware-realism.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hardware-realism.d.ts","sourceRoot":"","sources":["../../src/fingerprinting/hardware-realism.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AA0BH;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,2BAA2B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAInF,CAAC;AAKF;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAKzF;AAED;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CASxG;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAe/E;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMxD;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACpC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,IAAI,EAAE,MAAM,GACb,MAAM,CAOR"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hardware- and OS-realism helpers shared by BOTH injection paths.
|
|
3
|
+
*
|
|
4
|
+
* The native (C++ FingerprintConfig) path and the JS-injection path each used
|
|
5
|
+
* to carry their own copy of these decisions, and they disagreed - which is how
|
|
6
|
+
* issue #137 happened:
|
|
7
|
+
*
|
|
8
|
+
* - The native path fell back to a macOS platform version on LINUX profiles,
|
|
9
|
+
* because 90% of the harvested Linux pool rows carry no platform version and
|
|
10
|
+
* the fallback was a bare "15.0.0". A Linux Chrome reporting a Sequoia
|
|
11
|
+
* version is a contradiction on its own, and the JS path meanwhile used
|
|
12
|
+
* kernel-shaped values for Linux, so the two paths also disagreed with each
|
|
13
|
+
* other.
|
|
14
|
+
* - The native path resampled the pool's implausible `deviceMemory` values
|
|
15
|
+
* (0 / 1 / 2 / 4 GB on machines that have never shipped with less than 8);
|
|
16
|
+
* the JS path baked the raw value into the page, and because `0` is falsy it
|
|
17
|
+
* skipped the override entirely and leaked the HOST's real RAM.
|
|
18
|
+
* - The storage quota was derived from the RAW pool memory while the page
|
|
19
|
+
* reported the resampled value, so a session could claim 32 GB of RAM with a
|
|
20
|
+
* 1 GB machine's disk quota.
|
|
21
|
+
*
|
|
22
|
+
* Everything here is a pure function of (seed, input), so both paths produce the
|
|
23
|
+
* same values for the same session and the whole surface stays coherent.
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Memory sizes a real consumer machine reports. Chrome on desktop no longer
|
|
27
|
+
* clamps `navigator.deviceMemory` to the legacy W3C spec buckets - it reports
|
|
28
|
+
* the raw host RAM in GB (verified against a real Chrome on a 32 GB Mac, which
|
|
29
|
+
* reports 32). The upstream fingerprint pool still carries the old capped
|
|
30
|
+
* values, so anything at or below 8 is resampled.
|
|
31
|
+
*/
|
|
32
|
+
const PLAUSIBLE_RAW_MEMORY = new Set([16, 24, 32, 48, 64, 96, 128]);
|
|
33
|
+
/**
|
|
34
|
+
* Cumulative-weight table over a realistic 2026 consumer RAM distribution. 8 GB
|
|
35
|
+
* survives as a minority (older Apple Silicon and budget PCs) - Apple's base
|
|
36
|
+
* configuration has been 16 GB since the M4 generation.
|
|
37
|
+
*/
|
|
38
|
+
const MEMORY_DISTRIBUTION = [
|
|
39
|
+
[8, 15],
|
|
40
|
+
[16, 55],
|
|
41
|
+
[24, 70],
|
|
42
|
+
[32, 90],
|
|
43
|
+
[48, 95],
|
|
44
|
+
[64, 99],
|
|
45
|
+
[128, 100],
|
|
46
|
+
];
|
|
47
|
+
/**
|
|
48
|
+
* UA-CH `platformVersion` candidates per `navigator.platform`.
|
|
49
|
+
*
|
|
50
|
+
* - **Linux** is the empty string. Chromium's `GetPlatformVersion()`
|
|
51
|
+
* (components/embedder_support/user_agent_utils.cc) returns `std::string()` on
|
|
52
|
+
* Linux once the platform-version reduction is enabled, and the harvested pool
|
|
53
|
+
* corroborates it: 90% of real Linux rows carry no platform version at all.
|
|
54
|
+
* Never a version number here, and never a macOS one.
|
|
55
|
+
* - **macOS** is Tahoe-era. Measured on a real macOS host running Chrome 150:
|
|
56
|
+
* `sec-ch-ua-platform-version: "26.3.0"`. The pool agrees, with 57% of mac
|
|
57
|
+
* rows on 26.x. Repeats weight the distribution toward the current release.
|
|
58
|
+
* - **Windows** keeps the UA-CH reduced mapping, which is overwhelmingly 15.0.0
|
|
59
|
+
* for Windows 11 with a small tail at 14.0.0.
|
|
60
|
+
*/
|
|
61
|
+
export const PLATFORM_VERSION_CANDIDATES = {
|
|
62
|
+
'Win32': ['15.0.0', '15.0.0', '15.0.0', '14.0.0'],
|
|
63
|
+
'MacIntel': ['26.3.0', '26.3.0', '26.2.0', '26.1.0', '26.0.0', '15.6.0', '15.5.0'],
|
|
64
|
+
'Linux x86_64': [''],
|
|
65
|
+
};
|
|
66
|
+
/** Platform used when the requested one is unknown - desktop Windows dominates the population. */
|
|
67
|
+
const PLATFORM_VERSION_FALLBACK_KEY = 'Win32';
|
|
68
|
+
/**
|
|
69
|
+
* Resolve the UA-CH `platformVersion` for a platform, deterministically per
|
|
70
|
+
* seed. Both injection paths call this, so the JS override, the native config
|
|
71
|
+
* and the `sec-ch-ua-platform-version` header cannot disagree.
|
|
72
|
+
*/
|
|
73
|
+
export function resolvePlatformVersion(platform, seed) {
|
|
74
|
+
const candidates = PLATFORM_VERSION_CANDIDATES[platform ?? '']
|
|
75
|
+
?? PLATFORM_VERSION_CANDIDATES[PLATFORM_VERSION_FALLBACK_KEY];
|
|
76
|
+
const index = Math.abs(Math.trunc(Number.isFinite(seed) ? seed : 0)) % candidates.length;
|
|
77
|
+
return candidates[index];
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Pick a `navigator.deviceMemory` that a real machine of this class would
|
|
81
|
+
* report. Plausible upstream values pass through untouched; the pool's legacy
|
|
82
|
+
* spec-bucketed values (≤ 8 GB, including 0) are resampled from
|
|
83
|
+
* `MEMORY_DISTRIBUTION`.
|
|
84
|
+
*
|
|
85
|
+
* Guaranteed to return at least 8, so no caller can end up with a falsy value -
|
|
86
|
+
* that is what silently disabled the JS-path override and leaked the host's RAM.
|
|
87
|
+
*/
|
|
88
|
+
export function deriveRealisticDeviceMemory(seed, rawFromFingerprint) {
|
|
89
|
+
if (typeof rawFromFingerprint === 'number' && PLAUSIBLE_RAW_MEMORY.has(rawFromFingerprint)) {
|
|
90
|
+
return rawFromFingerprint;
|
|
91
|
+
}
|
|
92
|
+
const pick = Math.abs(Math.trunc(Number.isFinite(seed) ? seed : 0)) % 100;
|
|
93
|
+
for (const [gb, cumulative] of MEMORY_DISTRIBUTION) {
|
|
94
|
+
if (pick < cumulative)
|
|
95
|
+
return gb;
|
|
96
|
+
}
|
|
97
|
+
return 16;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* `navigator.storage.estimate().quota`, pinned per session so the host's real
|
|
101
|
+
* disk never leaks and so the same profile reports the same quota on every host.
|
|
102
|
+
*
|
|
103
|
+
* MUST be called with the memory value we actually report, not the raw pool
|
|
104
|
+
* value - the point is coherence between the two. Chrome's StorageManager
|
|
105
|
+
* reports roughly 60% of total disk space; the ±10% seed-driven jitter keeps
|
|
106
|
+
* different sessions from sharing one quota.
|
|
107
|
+
*/
|
|
108
|
+
export function deriveStorageQuota(seed, deviceMemoryGB) {
|
|
109
|
+
// eslint-disable-next-line no-bitwise -- low bit selects between two SSD sizes
|
|
110
|
+
const lowBit = seed & 1;
|
|
111
|
+
let ssdSizeGB;
|
|
112
|
+
if (deviceMemoryGB <= 8) {
|
|
113
|
+
ssdSizeGB = lowBit ? 256 : 512;
|
|
114
|
+
}
|
|
115
|
+
else if (deviceMemoryGB <= 16) {
|
|
116
|
+
ssdSizeGB = lowBit ? 512 : 1024;
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
ssdSizeGB = lowBit ? 1024 : 2048;
|
|
120
|
+
}
|
|
121
|
+
// eslint-disable-next-line no-bitwise -- byte 1 of the seed drives the jitter
|
|
122
|
+
const jitterFraction = (((seed >>> 8) & 0xFF) / 255) * 0.2 - 0.1;
|
|
123
|
+
const totalBytes = ssdSizeGB * 1024 * 1024 * 1024;
|
|
124
|
+
return Math.floor(totalBytes * (0.60 + jitterFraction));
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Stable non-negative hash of a session key, for paths that hold a seed STRING
|
|
128
|
+
* (the JS injector's proxy session key) rather than the numeric seed the native
|
|
129
|
+
* config generator computes. Math-only so the no-bitwise lint rule stays happy.
|
|
130
|
+
*/
|
|
131
|
+
export function stableSeedFromString(key) {
|
|
132
|
+
let hash = 0x811C9DC5;
|
|
133
|
+
for (let i = 0; i < key.length; i++) {
|
|
134
|
+
hash = (hash * 31 + key.charCodeAt(i)) % 0x7FFFFFFF;
|
|
135
|
+
}
|
|
136
|
+
return hash;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* The platform version to advertise for a profile: the profile's own value when
|
|
140
|
+
* it has a usable one, otherwise a seeded candidate - except on Linux, where the
|
|
141
|
+
* answer is always the empty string.
|
|
142
|
+
*
|
|
143
|
+
* Linux is unconditional because the profile cannot be trusted there: 10% of the
|
|
144
|
+
* harvested Linux rows carry a kernel-shaped version (6.x) from before Chrome
|
|
145
|
+
* reduced the Linux platform version, and advertising one today announces a
|
|
146
|
+
* value current Chrome never sends.
|
|
147
|
+
*/
|
|
148
|
+
export function normalizePlatformVersion(platform, profileValue, seed) {
|
|
149
|
+
if (platform === 'Linux x86_64') {
|
|
150
|
+
return '';
|
|
151
|
+
}
|
|
152
|
+
return profileValue && profileValue.length > 0
|
|
153
|
+
? profileValue
|
|
154
|
+
: resolvePlatformVersion(platform, seed);
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=hardware-realism.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hardware-realism.js","sourceRoot":"","sources":["../../src/fingerprinting/hardware-realism.ts"],"names":[],"mappings":"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"}
|