diff --git a/scripts/lib/verifier-host-environment.mjs b/scripts/lib/verifier-host-environment.mjs index 73c04b0..fde20f7 100644 --- a/scripts/lib/verifier-host-environment.mjs +++ b/scripts/lib/verifier-host-environment.mjs @@ -2,9 +2,18 @@ * Variables a Windows child process needs from the host even when a verifier * isolates everything else. Without SystemRoot, Node aborts at startup with * `Assertion failed: ncrypto::CSPRNG(nullptr, 0)`; without ComSpec and PATHEXT - * npm `.cmd` shims such as `qwen.cmd` cannot be resolved or run. + * npm `.cmd` shims such as `qwen.cmd` cannot be resolved or run; without TEMP + * and TMP, Windows falls back to C:\Windows\temp, which a normal account may + * not open, and analysis fails at startup with "Access is denied". */ -const WINDOWS_HOST_VARIABLES = ["SystemRoot", "WINDIR", "ComSpec", "PATHEXT"]; +const WINDOWS_HOST_VARIABLES = [ + "SystemRoot", + "WINDIR", + "ComSpec", + "PATHEXT", + "TEMP", + "TMP", +]; /** Host variables to keep in an isolated verifier environment. */ export const verifierHostEnvironment = ( diff --git a/tests/boundary/process/verifierHostEnvironment.test.ts b/tests/boundary/process/verifierHostEnvironment.test.ts index 02ec2d4..a6fcb74 100644 --- a/tests/boundary/process/verifierHostEnvironment.test.ts +++ b/tests/boundary/process/verifierHostEnvironment.test.ts @@ -20,6 +20,8 @@ describe("isolated verifier environments", () => { windir: "C:\\Windows", ComSpec: "C:\\Windows\\system32\\cmd.exe", PATHEXT: ".COM;.EXE;.BAT;.CMD", + Temp: "C:\\Users\\someone\\AppData\\Local\\Temp", + TMP: "C:\\Users\\someone\\AppData\\Local\\Temp", USERPROFILE: "C:\\Users\\someone", SECRET: "not copied", }, @@ -30,6 +32,10 @@ describe("isolated verifier environments", () => { WINDIR: "C:\\Windows", ComSpec: "C:\\Windows\\system32\\cmd.exe", PATHEXT: ".COM;.EXE;.BAT;.CMD", + // Without TEMP and TMP Windows falls back to C:\Windows\temp, which a + // normal account may not open: analysis then fails with access denied. + TEMP: "C:\\Users\\someone\\AppData\\Local\\Temp", + TMP: "C:\\Users\\someone\\AppData\\Local\\Temp", }); }); @@ -52,17 +58,21 @@ describe("isolated verifier environments", () => { ); it.runIf(process.platform === "win32")( - "lets a child Node process start on Windows", + "lets a child Node process start on Windows with the account's temp directory", async () => { const { stdout } = await execute( process.execPath, [ "-e", - "process.stdout.write(String(require('node:crypto').randomInt(1, 2)))", + "process.stdout.write(JSON.stringify({ random: require('node:crypto').randomInt(1, 2), temp: require('node:os').tmpdir() }))", ], { env: { ...verifierHostEnvironment(), PATH: process.env.PATH ?? "" } }, ); - expect(stdout).toBe("1"); + const child = JSON.parse(stdout) as { random: number; temp: string }; + expect(child.random).toBe(1); + expect(child.temp.toLowerCase()).toBe( + (process.env.TEMP ?? "").toLowerCase(), + ); }, ); });