From 3c668851114b7dac932774ebb9d218e3af35c0ad Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 16 May 2026 14:14:41 +0000 Subject: [PATCH 1/5] Initial plan From aa5f2f43e185ec975a1123f184c59112a9a54250 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 16 May 2026 14:20:56 +0000 Subject: [PATCH 2/5] Use crypto random bytes for workdir IDs --- packages/runtime/src/band-server.ts | 4 ++-- packages/runtime/test/unit/band-server.test.ts | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 packages/runtime/test/unit/band-server.test.ts diff --git a/packages/runtime/src/band-server.ts b/packages/runtime/src/band-server.ts index 211c568..1a6fec6 100644 --- a/packages/runtime/src/band-server.ts +++ b/packages/runtime/src/band-server.ts @@ -20,7 +20,7 @@ */ import { Hono } from "hono"; -import { createHash } from "crypto"; +import { createHash, randomBytes } from "crypto"; const BAND_RUNNER_USER = "band-runner"; let executing = false; @@ -137,7 +137,7 @@ function shellIgnoreError(cmd: string): void { } function randomId(): string { - return Math.random().toString(36).slice(2, 10); + return randomBytes(8).toString("hex"); } /** Reject values containing shell metacharacters. Used for any band-config value interpolated into shell commands. */ diff --git a/packages/runtime/test/unit/band-server.test.ts b/packages/runtime/test/unit/band-server.test.ts new file mode 100644 index 0000000..bfe3cd6 --- /dev/null +++ b/packages/runtime/test/unit/band-server.test.ts @@ -0,0 +1,13 @@ +import { describe, expect, test } from "bun:test"; +import { readFileSync } from "fs"; +import { join } from "path"; + +const source = readFileSync(join(import.meta.dir, "../../src/band-server.ts"), "utf8"); + +describe("band-server", () => { + test("generates workdir IDs with crypto random bytes", () => { + expect(source).toContain('import { createHash, randomBytes } from "crypto";'); + expect(source).toContain('return randomBytes(8).toString("hex");'); + expect(source).not.toContain("Math.random()"); + }); +}); From 3f95f87018850aa1e1675824873e52e0d2cd9fc8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 16 May 2026 14:22:16 +0000 Subject: [PATCH 3/5] Make workdir ID test behavioral --- packages/runtime/src/band-server.ts | 7 ++---- packages/runtime/src/random-id.ts | 5 ++++ .../runtime/test/unit/band-server.test.ts | 24 ++++++++++++------- 3 files changed, 23 insertions(+), 13 deletions(-) create mode 100644 packages/runtime/src/random-id.ts diff --git a/packages/runtime/src/band-server.ts b/packages/runtime/src/band-server.ts index 1a6fec6..bf5232b 100644 --- a/packages/runtime/src/band-server.ts +++ b/packages/runtime/src/band-server.ts @@ -20,7 +20,8 @@ */ import { Hono } from "hono"; -import { createHash, randomBytes } from "crypto"; +import { createHash } from "crypto"; +import { randomId } from "./random-id"; const BAND_RUNNER_USER = "band-runner"; let executing = false; @@ -136,10 +137,6 @@ function shellIgnoreError(cmd: string): void { Bun.spawnSync(["sudo", "bash", "-c", cmd]); } -function randomId(): string { - return randomBytes(8).toString("hex"); -} - /** Reject values containing shell metacharacters. Used for any band-config value interpolated into shell commands. */ function shellSafe(value: string, label: string): string { if (/[;`$(){}|&<>!\\"\n\r]/.test(value)) { diff --git a/packages/runtime/src/random-id.ts b/packages/runtime/src/random-id.ts new file mode 100644 index 0000000..b173033 --- /dev/null +++ b/packages/runtime/src/random-id.ts @@ -0,0 +1,5 @@ +import { randomBytes } from "crypto"; + +export function randomId(): string { + return randomBytes(8).toString("hex"); +} diff --git a/packages/runtime/test/unit/band-server.test.ts b/packages/runtime/test/unit/band-server.test.ts index bfe3cd6..af27fd9 100644 --- a/packages/runtime/test/unit/band-server.test.ts +++ b/packages/runtime/test/unit/band-server.test.ts @@ -1,13 +1,21 @@ import { describe, expect, test } from "bun:test"; -import { readFileSync } from "fs"; -import { join } from "path"; - -const source = readFileSync(join(import.meta.dir, "../../src/band-server.ts"), "utf8"); +import { randomId } from "../../src/random-id"; describe("band-server", () => { - test("generates workdir IDs with crypto random bytes", () => { - expect(source).toContain('import { createHash, randomBytes } from "crypto";'); - expect(source).toContain('return randomBytes(8).toString("hex");'); - expect(source).not.toContain("Math.random()"); + test("generates 16-character hex IDs", () => { + expect(randomId()).toMatch(/^[0-9a-f]{16}$/); + }); + + test("does not use Math.random", () => { + const originalRandom = Math.random; + Math.random = () => { + throw new Error("Math.random should not be used for workdir IDs"); + }; + + try { + expect(randomId()).toMatch(/^[0-9a-f]{16}$/); + } finally { + Math.random = originalRandom; + } }); }); From 6824e552df1545ac9435e5bdfe1eebe653776596 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 16 May 2026 14:23:13 +0000 Subject: [PATCH 4/5] Rename random ID test suite --- packages/runtime/test/unit/band-server.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/runtime/test/unit/band-server.test.ts b/packages/runtime/test/unit/band-server.test.ts index af27fd9..f272c14 100644 --- a/packages/runtime/test/unit/band-server.test.ts +++ b/packages/runtime/test/unit/band-server.test.ts @@ -1,7 +1,7 @@ import { describe, expect, test } from "bun:test"; import { randomId } from "../../src/random-id"; -describe("band-server", () => { +describe("randomId", () => { test("generates 16-character hex IDs", () => { expect(randomId()).toMatch(/^[0-9a-f]{16}$/); }); From 0c32461ecdc7c48d684b3781e763351b84733635 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 16 May 2026 14:24:12 +0000 Subject: [PATCH 5/5] Rename random ID test file --- .../runtime/test/unit/{band-server.test.ts => random-id.test.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/runtime/test/unit/{band-server.test.ts => random-id.test.ts} (100%) diff --git a/packages/runtime/test/unit/band-server.test.ts b/packages/runtime/test/unit/random-id.test.ts similarity index 100% rename from packages/runtime/test/unit/band-server.test.ts rename to packages/runtime/test/unit/random-id.test.ts