From 0f9c2205d5f1f7f1a64900ed4540e33fc1d7a443 Mon Sep 17 00:00:00 2001 From: Matt Gibson Date: Tue, 26 Oct 2021 08:45:32 -0500 Subject: [PATCH] Dynamically set electron user agent (#524) * Dynamically set electron user agent * PR review * linter fixes * Test agent static version does not change * Fix formatting --- electron/src/utils.ts | 16 ++++++++++++++++ electron/src/window.main.ts | 18 +++++++++++------- spec/electron/utils.spec.ts | 27 +++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 spec/electron/utils.spec.ts diff --git a/electron/src/utils.ts b/electron/src/utils.ts index 80eb09794f..ce4de6058d 100644 --- a/electron/src/utils.ts +++ b/electron/src/utils.ts @@ -46,3 +46,19 @@ export function isSnapStore() { export function isWindowsPortable() { return process.platform === 'win32' && process.env.PORTABLE_EXECUTABLE_DIR != null; } + +/** + * Sanitize user agent so external resources used by the app can't built data on our users. + */ +export function cleanUserAgent(userAgent: string): string { + const userAgentItem = (startString: string, endString: string) => { + const startIndex = userAgent.indexOf(startString); + return userAgent.substring(startIndex, userAgent.indexOf(endString, startIndex) + 1); + }; + const systemInformation = '(Windows NT 10.0; Win64; x64)'; + + // Set system information, remove bitwarden, and electron information + return userAgent.replace(userAgentItem('(', ')'), systemInformation) + .replace(userAgentItem('Bitwarden', ' '), '') + .replace(userAgentItem('Electron', ' '), ''); +} diff --git a/electron/src/window.main.ts b/electron/src/window.main.ts index 28b3ca0abe..f51dc11410 100644 --- a/electron/src/window.main.ts +++ b/electron/src/window.main.ts @@ -11,6 +11,7 @@ import { StorageService } from 'jslib-common/abstractions/storage.service'; import { ElectronConstants } from './electronConstants'; import { + cleanUserAgent, isDev, isMacAppStore, isSnapStore, @@ -139,13 +140,16 @@ export class WindowMain { this.win.show(); // and load the index.html of the app. - this.win.loadURL(url.format({ - protocol: 'file:', - pathname: path.join(__dirname, '/index.html'), - slashes: true, - }), { - userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0', - }); + this.win.loadURL(url.format( + { + protocol: 'file:', + pathname: path.join(__dirname, '/index.html'), + slashes: true, + }), + { + userAgent: cleanUserAgent(this.win.webContents.userAgent), + } + ); // Open the DevTools. if (isDev()) { diff --git a/spec/electron/utils.spec.ts b/spec/electron/utils.spec.ts new file mode 100644 index 0000000000..b350a82da9 --- /dev/null +++ b/spec/electron/utils.spec.ts @@ -0,0 +1,27 @@ +import { cleanUserAgent } from 'jslib-electron/utils'; + +const expectedUserAgent = `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${process.versions.chrome} Safari/537.36`; + +describe('cleanUserAgent', () => { + it('cleans mac agent', () => { + const initialMacAgent = `Mozilla/5.0 (Macintosh; Intel Mac OS X 11_6_0) AppleWebKit/537.36 (KHTML, like Gecko) Bitwarden/${process.version} Chrome/${process.versions.chrome} Electron/${process.versions.electron} Safari/537.36`; + expect(cleanUserAgent(initialMacAgent)).toEqual(expectedUserAgent); + }); + + it('cleans windows agent', () => { + const initialWindowsAgent = `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Bitwarden/${process.version} Chrome/${process.versions.chrome} Electron/${process.versions.electron} Safari/537.36`; + expect(cleanUserAgent(initialWindowsAgent)).toEqual(expectedUserAgent); + }); + + it('cleans linux agent', () => { + const initialWindowsAgent = `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Bitwarden/${process.version} Chrome/${process.versions.chrome} Electron/${process.versions.electron} Safari/537.36`; + expect(cleanUserAgent(initialWindowsAgent)).toEqual(expectedUserAgent); + }); + + it('does not change version numbers', () => { + const expected = `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36`; + const initialAgent = `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Bitwarden/1.28.3 Chrome/87.0.4280.141 Electron/11.4.5 Safari/537.36`; + + expect(cleanUserAgent(initialAgent)).toEqual(expected); + }); +});