From 1cf90367ee1615f09e4b5cf71f9ddddf4a984084 Mon Sep 17 00:00:00 2001 From: sereneblue Date: Sun, 28 Mar 2021 23:09:12 -0400 Subject: [PATCH] feat: improve browser profile spoofing (#494) --- src/lib/inject.ts | 4 + src/lib/spoof/quirks.ts | 170 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 174 insertions(+) create mode 100644 src/lib/spoof/quirks.ts diff --git a/src/lib/inject.ts b/src/lib/inject.ts index 553b3bc2..a29df3d7 100644 --- a/src/lib/inject.ts +++ b/src/lib/inject.ts @@ -9,6 +9,7 @@ import language from './spoof/language'; import media from './spoof/media'; import mediaSpoof from './spoof/mediaSpoof'; import navigator from './spoof/navigator'; +import quirks from './spoof/quirks'; import referer from './spoof/referer'; import screen from './spoof/screen'; import timezone from './spoof/timezone'; @@ -51,6 +52,7 @@ class Injector { if (p) { this.spoof.metadata['profileOS'] = p.osId; + this.spoof.metadata['browser'] = p.browser; } else { // get real profile let profileId: string = ''; @@ -87,6 +89,7 @@ class Injector { } this.spoof.metadata['profileOS'] = profileId; + this.spoof.metadata['browser'] = 'firefox'; } if (settings.options.blockMediaDevices) { @@ -214,6 +217,7 @@ class Injector { } this.updateInjectionData(navigator); + this.updateInjectionData(quirks); } } diff --git a/src/lib/spoof/quirks.ts b/src/lib/spoof/quirks.ts new file mode 100644 index 00000000..a3757d44 --- /dev/null +++ b/src/lib/spoof/quirks.ts @@ -0,0 +1,170 @@ +export default { + type: 'custom', + data: ` + let data = CHAMELEON_SPOOF.get(spoofContext); + let uniqId = Math.floor(Math.random() * (1000) + 1000); + let startTime = new Date().getTime(); + let randLoadTime = Math.floor(Math.random() * 1000); + + if (data.browser !== "firefox") { + delete window.InstallTrigger; + delete window.InstallTriggerImpl; + } + + if (data.browser === "edge" || data.browser === "chrome") { + spoofContext.chrome = { + app: { + InstallState: { + DISABLED: "disabled", + INSTALLED: "installed", + NOT_INSTALLED: "not_installed" + }, + RunningState: { + CANNOT_RUN: "cannot_run", + READY_TO_RUN: "ready_to_run", + RUNNING: "running" + }, + getDetails() { + return null; + }, + getIsInstalled() { + return false; + }, + installState() { + return "not_installed"; + }, + isInstalled: false, + runningState() { + return "cannot_run"; + } + }, + csi() { + return { + onloadT: startTime + randLoadTime, + pageT: new Date().getTime() - startTime, + startE: startTime, + tran: 15 + } + }, + loadTimes() { + return { + commitLoadTime: startTime, + connectionInfo: "http/1.0", + finishDocumentLoadTime: 0, + finishLoadTime: 0, + firstPaintAfterLoadTime: 0, + firstPaintTime: 0, + navigationType: "Reload", + npnNegotiatedProtocol: "unknown", + requestTime: startTime, + startLoadTime: startTime, + wasAlternateProtocolAvailable: false, + wasFetchedViaSpdy: false, + wasNpnNegotiated: false + } + }, + runtime: { + OnInstalledReason: { + CHROME_UPDATE: "chrome_update", + INSTALL: "install", + SHARED_MODULE_UPDATE: "shared_module_update", + UPDATE: "update" + }, + OnRestartRequiredReason: { + APP_UPDATE: "app_update", + OS_UPDATE: "os_update", + PERIODIC: "periodic" + }, + PlatformArch: { + ARM: "arm", + ARM64: "arm64", + MIPS: "mips", + MIPS64: "mips64", + X86_32: "x86-32", + X86_64: "x86-64" + }, + PlatformNaclArch: { + ARM: "arm", + ARM64: "arm64", + MIPS: "mips", + MIPS64: "mips64", + X86_32: "x86-32", + X86_64: "x86-64" + }, + PlatformOs: { + ANDROID: "android", + CROS: "cros", + LINUX: "linux", + MAC: "mac", + OPENBSD: "openbsd", + WIN: "win" + }, + RequestUpdateCheckStatus: { + NO_UPDATE: "no_update", + THROTTLED: "throttled", + UPDATE_AVAILABLE: "update_available" + }, + connect() { + // do nothing + }, + id: undefined, + sendMessage() { + // do nothing + } + } + }; + } + + if (data.browser === "safari") { + const SafariRemoteNotification = { + async requestPermission(url, websitePushID, userInfo, callback) { + callback({ + permission: 'denied' + }) + }, + permission() { + return { + permission: 'denied' + } + }, + toString: () => { + return "[object SafariRemoteNotification]"; + } + }; + + spoofContext.safari = { + pushNotification: SafariRemoteNotification + }; + } + + if (data.browser === "ie") { + spoofContext.document.documentMode = 11; + + Object.defineProperty(spoofContext.document, 'uniqueID', { + get() { + ++uniqId; + return 'ms__id' + uniqId; + } + }); + + // stub for MSInputMethodContext + spoofContext.MSInputMethodContext = { + compositionEndOffset: 0, + compositionStartOffset: 0, + target: null, + oncandidatewindowhide: () => {}, + oncandidatewindowhide: () => {}, + oncandidatewindowhide: () => {}, + getCandidateWindowClientRect: () => {}, + getCompositionAlternatives: () => {}, + hasComposition: () => {}, + isCandidateWindowVisible: () => {} + }; + + Object.setPrototypeOf(spoofContext.MSInputMethodContext, EventTarget.prototype); + + spoofContext.ActiveXObject = undefined; + spoofContext.msCrypto = spoofContext.crypto; + } + `, +};