From 50fe71372181a3da0ae71c14e5c83505dde17245 Mon Sep 17 00:00:00 2001 From: "R. N. West" <98110034+rnwst@users.noreply.github.com> Date: Thu, 13 Nov 2025 21:44:37 +0000 Subject: [PATCH] fix: Ensured `navigator.webdriver != true` in launched Chromium The `--remote-debugging-pipe` flag causes `navigator.webdriver == true` in the launched Chromium instance (provided there is no existing Chromium instance). The `--disable-blink-features=AutomationControlled` flag needs to be passed to prevent this and avoid breaking websites with bot detection features. --- src/extension-runners/chromium.js | 15 ++++++++ .../test-extension-runners/test.chromium.js | 36 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/extension-runners/chromium.js b/src/extension-runners/chromium.js index 047c7874bc..a2f91d813c 100644 --- a/src/extension-runners/chromium.js +++ b/src/extension-runners/chromium.js @@ -256,6 +256,21 @@ export class ChromiumExtensionRunner { chromeFlags.push(...this.params.args); } + // `--remote-debugging-pipe` results in `navigator.webdriver == true` in + // the launched Chromium instance (unless a Chromium session exists + // already, in which case the existing session is used, which typically + // has `navigator.webdriver == false`). This breaks websites with bot + // detection features. The following flag prevents this. + // Only pass this flag if `--enable-blink-features=AutomationControlled` + // is not passed. + if ( + !chromeFlags.some((flag) => + /^--enable-blink-features=(.*,)?AutomationControlled(,|$)/.test(flag), + ) + ) { + chromeFlags.push('--disable-blink-features=AutomationControlled'); + } + // eslint-disable-next-line prefer-const let { userDataDir, profileDirName } = await ChromiumExtensionRunner.getProfilePaths( diff --git a/tests/unit/test-extension-runners/test.chromium.js b/tests/unit/test-extension-runners/test.chromium.js index 084d62891e..c3a22a116f 100644 --- a/tests/unit/test-extension-runners/test.chromium.js +++ b/tests/unit/test-extension-runners/test.chromium.js @@ -117,6 +117,7 @@ describe('util/extension-runners/chromium', async () => { ...DEFAULT_CHROME_FLAGS, '--remote-debugging-pipe', '--enable-unsafe-extension-debugging', + '--disable-blink-features=AutomationControlled', ], startingUrl: undefined, }); @@ -227,6 +228,7 @@ describe('util/extension-runners/chromium', async () => { ...DEFAULT_CHROME_FLAGS, '--remote-debugging-pipe', '--enable-unsafe-extension-debugging', + '--disable-blink-features=AutomationControlled', ], startingUrl: undefined, }); @@ -250,6 +252,7 @@ describe('util/extension-runners/chromium', async () => { ...DEFAULT_CHROME_FLAGS, '--remote-debugging-pipe', '--enable-unsafe-extension-debugging', + '--disable-blink-features=AutomationControlled', 'url2', 'url3', ], @@ -281,6 +284,7 @@ describe('util/extension-runners/chromium', async () => { '--arg1', 'arg2', '--arg3', + '--disable-blink-features=AutomationControlled', 'url2', 'url3', ], @@ -290,6 +294,32 @@ describe('util/extension-runners/chromium', async () => { await runnerInstance.exit(); }); + it("doesn't disable `AutomationControlled` when corresponding arg is passed", async () => { + // If the `--enable-blink-features=AutomationControlled` flag is passed, + // `--disable-blink-features=AutomationControlled` should not be passed. + const { params } = prepareExtensionRunnerParams({ + params: { + args: ['--enable-blink-features=CSSVariables,AutomationControlled'], + }, + }); + + const runnerInstance = new ChromiumExtensionRunner(params); + await runnerInstance.run(); + + sinon.assert.calledWithMatch(params.chromiumLaunch, { + ignoreDefaultFlags: true, + chromePath: undefined, + chromeFlags: [ + ...DEFAULT_CHROME_FLAGS, + '--remote-debugging-pipe', + '--enable-unsafe-extension-debugging', + '--enable-blink-features=CSSVariables,AutomationControlled', + ], + }); + + await runnerInstance.exit(); + }); + it('does use a random user-data-dir', async () => { const { params } = prepareExtensionRunnerParams({ params: {}, @@ -334,6 +364,7 @@ describe('util/extension-runners/chromium', async () => { ...DEFAULT_CHROME_FLAGS, '--remote-debugging-pipe', '--enable-unsafe-extension-debugging', + '--disable-blink-features=AutomationControlled', ], startingUrl: undefined, }); @@ -375,6 +406,7 @@ describe('util/extension-runners/chromium', async () => { ...DEFAULT_CHROME_FLAGS, '--remote-debugging-pipe', '--enable-unsafe-extension-debugging', + '--disable-blink-features=AutomationControlled', '--profile-directory=profile', ], startingUrl: undefined, @@ -417,6 +449,7 @@ describe('util/extension-runners/chromium', async () => { ...DEFAULT_CHROME_FLAGS, '--remote-debugging-pipe', '--enable-unsafe-extension-debugging', + '--disable-blink-features=AutomationControlled', `--profile-directory=${profileDirName}`, ], startingUrl: undefined, @@ -512,6 +545,7 @@ describe('util/extension-runners/chromium', async () => { ...DEFAULT_CHROME_FLAGS, '--remote-debugging-pipe', '--enable-unsafe-extension-debugging', + '--disable-blink-features=AutomationControlled', '--profile-directory=profile', ], startingUrl: undefined, @@ -548,6 +582,7 @@ describe('util/extension-runners/chromium', async () => { ...DEFAULT_CHROME_FLAGS, '--remote-debugging-pipe', '--enable-unsafe-extension-debugging', + '--disable-blink-features=AutomationControlled', ], startingUrl: undefined, }); @@ -558,6 +593,7 @@ describe('util/extension-runners/chromium', async () => { ...DEFAULT_CHROME_FLAGS, '--remote-debugging-pipe', '--load-extension=/fake/sourceDir', + '--disable-blink-features=AutomationControlled', ], startingUrl: undefined, });