From 8434d62d078e48d01342a18e79aba67db7612b0a Mon Sep 17 00:00:00 2001 From: Lyon <88232613+pikasTech@users.noreply.github.com> Date: Mon, 22 Jun 2026 09:06:10 +0800 Subject: [PATCH] fix(web-probe): enforce browser no-proxy launch (#641) Co-authored-by: Codex --- .../hwlab-node-web-observe-runner-source.ts | 23 ++++++++++++++++++- .../src/hwlab-node-web-probe-runner-source.ts | 23 ++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/scripts/src/hwlab-node-web-observe-runner-source.ts b/scripts/src/hwlab-node-web-observe-runner-source.ts index e80ff286..678eb98e 100644 --- a/scripts/src/hwlab-node-web-observe-runner-source.ts +++ b/scripts/src/hwlab-node-web-observe-runner-source.ts @@ -22,6 +22,7 @@ const screenshotIntervalMs = positiveInteger(process.env.UNIDESK_WEB_OBSERVE_SCR const maxSamples = positiveInteger(process.env.UNIDESK_WEB_OBSERVE_MAX_SAMPLES, 0); const viewport = parseViewport(process.env.UNIDESK_WEB_OBSERVE_VIEWPORT || "1440x900"); const playwrightProxy = proxyConfigFromEnv(baseUrl); +const chromiumLaunchOptions = chromiumLaunchOptionsForProxy(playwrightProxy); const pageId = "page-" + randomBytes(4).toString("hex"); const dirs = { commandsPending: path.join(stateDir, "commands", "pending"), @@ -63,7 +64,7 @@ try { await writeHeartbeat({ status: "starting" }); const launcher = await import(pathToFileURL(path.resolve("scripts/src/browser-launcher.mjs")).href); const { chromium } = await launcher.importPlaywright(); - browser = await launcher.launchChromium(chromium); + browser = await launcher.launchChromium(chromium, chromiumLaunchOptions); context = await browser.newContext({ viewport, ...(playwrightProxy === null ? {} : { proxy: playwrightProxy }) }); auth = await runControlCommand({ id: "startup-login", type: "login", createdAt: startedAt, source: "startup" }, async () => authenticate(context)); page = await context.newPage(); @@ -301,6 +302,21 @@ function proxyConfigFromEnv(targetBaseUrl) { return { server: raw }; } +function chromiumLaunchOptionsForProxy(proxy) { + const base = { env: browserProcessEnvWithoutProxy() }; + if (proxy === null) return { ...base, args: ["--no-proxy-server"] }; + return { ...base, proxy }; +} + +function browserProcessEnvWithoutProxy() { + const blocked = new Set(["HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY", "NO_PROXY", "http_proxy", "https_proxy", "all_proxy", "no_proxy"]); + const env = {}; + for (const [key, value] of Object.entries(process.env)) { + if (!blocked.has(key) && value !== undefined) env[key] = value; + } + return env; +} + function noProxyMatches(hostname, rawList) { const host = String(hostname || "").toLowerCase(); if (!host) return false; @@ -324,6 +340,11 @@ function publicNetwork(proxy) { server: publicProxyServer(proxy.server), valuesRedacted: true, }, + browser: { + proxyMode: proxy === null ? "direct-no-proxy-server" : "explicit-playwright-proxy", + proxyEnvCleared: true, + valuesRedacted: true, + }, valuesRedacted: true, }; } diff --git a/scripts/src/hwlab-node-web-probe-runner-source.ts b/scripts/src/hwlab-node-web-probe-runner-source.ts index e616b0c5..3d586935 100644 --- a/scripts/src/hwlab-node-web-probe-runner-source.ts +++ b/scripts/src/hwlab-node-web-probe-runner-source.ts @@ -18,6 +18,7 @@ const userScript = path.resolve(process.env.UNIDESK_WEB_PROBE_USER_SCRIPT || pat const timeoutMs = positiveInteger(process.env.UNIDESK_WEB_PROBE_TIMEOUT_MS, 30000); const viewport = parseViewport(process.env.UNIDESK_WEB_PROBE_VIEWPORT || "1440x900"); const playwrightProxy = proxyConfigFromEnv(baseUrl); +const chromiumLaunchOptions = chromiumLaunchOptionsForProxy(playwrightProxy); const artifactRecords = []; const readinessRecords = []; const stepRecords = []; @@ -34,7 +35,7 @@ try { userScriptSha256 = await sha256File(userScript).catch(() => null); const launcher = await import(pathToFileURL(path.resolve("scripts/src/browser-launcher.mjs")).href); const { chromium } = await launcher.importPlaywright(); - browser = await launcher.launchChromium(chromium); + browser = await launcher.launchChromium(chromium, chromiumLaunchOptions); context = await browser.newContext({ viewport, ...(playwrightProxy === null ? {} : { proxy: playwrightProxy }) }); auth = await authenticate(context); if (!auth.ok) throw new Error("auth-login-failed"); @@ -384,6 +385,21 @@ function proxyConfigFromEnv(targetBaseUrl) { return { server: raw }; } +function chromiumLaunchOptionsForProxy(proxy) { + const base = { env: browserProcessEnvWithoutProxy() }; + if (proxy === null) return { ...base, args: ["--no-proxy-server"] }; + return { ...base, proxy }; +} + +function browserProcessEnvWithoutProxy() { + const blocked = new Set(["HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY", "NO_PROXY", "http_proxy", "https_proxy", "all_proxy", "no_proxy"]); + const env = {}; + for (const [key, value] of Object.entries(process.env)) { + if (!blocked.has(key) && value !== undefined) env[key] = value; + } + return env; +} + function noProxyMatches(hostname, rawList) { const host = String(hostname || "").toLowerCase(); if (!host) return false; @@ -407,6 +423,11 @@ function publicNetwork(proxy) { server: publicProxyServer(proxy.server), valuesRedacted: true, }, + browser: { + proxyMode: proxy === null ? "direct-no-proxy-server" : "explicit-playwright-proxy", + proxyEnvCleared: true, + valuesRedacted: true, + }, valuesRedacted: true, }; }