From 7aecae863d8d4755cc1034931f2be7efb5367822 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Thu, 27 Aug 2026 08:56:53 +0200 Subject: [PATCH] Teach the pin inventory the conditional openai-client shape MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SSRF pin inventory asserted a literal unconditional pin in the openai-client; the previous commit made that pin conditional for the two person-typed base-URL tags. The guard now asserts the exact ternary — allowlist helper for gateway/admin-key, literal true as the floor — so neither the floor nor the condition can drift silently. --- src/lib/__tests__/ssrf-pin-inventory.test.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/lib/__tests__/ssrf-pin-inventory.test.ts b/src/lib/__tests__/ssrf-pin-inventory.test.ts index 6e598849a..b5b7d67c5 100644 --- a/src/lib/__tests__/ssrf-pin-inventory.test.ts +++ b/src/lib/__tests__/ssrf-pin-inventory.test.ts @@ -8,7 +8,8 @@ * A future edit that drops the pin (re-opening the SSRF surface) fails here * instead of shipping silently. * - * The LOCAL AI client is the deliberate exception: it stays CONDITIONAL + * The LOCAL AI client and (since v1.37.30) the openai-client's gateway and + * admin-key tags are the deliberate exceptions: they stay CONDITIONAL * (`requirePublicHost: !allowPrivate`) so an operator can opt into LAN hosts * via `ALLOW_LOCAL_AI_PRIVATE_HOSTS`. v1.18.7 (SECURITY LOW) — that flag is * now a host ALLOWLIST (`true` = any private host; a comma-separated list = @@ -26,8 +27,16 @@ const SRC = join(__dirname, ".."); const read = (rel: string) => readFileSync(join(SRC, rel), "utf8"); describe("SSRF requirePublicHost pin inventory", () => { - it("openai-client pins the BYO base-URL outbound unconditionally", () => { - expect(read("ai/openai-client.ts")).toMatch(/requirePublicHost:\s*true/); + // v1.37.30 — openai-client is no longer a blanket pin: the gateway and + // admin-key tags carry a person-typed base URL and route through the + // operator allowlist helper, with `true` as the ternary floor for every + // other tag (codex). We assert the exact conditional shape so a future + // edit can neither drop the floor nor widen the condition silently. + it("openai-client routes person-typed base URLs through the allowlist with a pinned floor", () => { + const src = read("ai/openai-client.ts"); + expect(src).toMatch( + /requirePublicHost:\s*this\.isGateway \|\| this\.type === "admin-key"\s*\? requirePublicHostFor\(this\.config\.baseUrl\)\s*:\s*true/, + ); }); it("anthropic-client pins the BYO base-URL outbound unconditionally", () => {