From 410a061eafbad22305b81a06fea214f8eac99539 Mon Sep 17 00:00:00 2001 From: Diego Rodrigues de Sa e Souza Date: Fri, 21 Aug 2026 08:02:16 -0300 Subject: [PATCH] fix(security): clear new CodeQL code-scanning alerts (round 2) (#10888) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Validado no worktree combinado: typecheck:core, changelog-integrity, file-size, lint todos verdes. Correção real dos 3 alertas CodeQL (HMAC em vez de hash bruto, URL parsing em vez de substring, dismiss documentado). CI vermelho é o base-red já rastreado em #9985. --- open-sse/executors/freebuff.ts | 4 +++- open-sse/services/cursorApiKeyAuth.ts | 6 +++++- tests/unit/antigravity-byop-account-rotation.test.ts | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/open-sse/executors/freebuff.ts b/open-sse/executors/freebuff.ts index bc2de30f63..c2cf5bdbc3 100644 --- a/open-sse/executors/freebuff.ts +++ b/open-sse/executors/freebuff.ts @@ -1,3 +1,5 @@ +import { randomInt } from "node:crypto"; + import { BaseExecutor, type ExecuteInput, @@ -20,7 +22,7 @@ function generateClientSessionId(): string { const alphabet = "0123456789abcdefghijklmnopqrstuvwxyz"; let out = ""; for (let i = 0; i < 13; i++) { - out += alphabet[Math.floor(Math.random() * alphabet.length)]; + out += alphabet[randomInt(alphabet.length)]; } return out; } diff --git a/open-sse/services/cursorApiKeyAuth.ts b/open-sse/services/cursorApiKeyAuth.ts index 60c3385783..126123b119 100644 --- a/open-sse/services/cursorApiKeyAuth.ts +++ b/open-sse/services/cursorApiKeyAuth.ts @@ -50,8 +50,12 @@ export function isCursorApiKey(value: unknown): value is string { return typeof value === "string" && value.startsWith(CURSOR_API_KEY_PREFIX); } +// Session-cache key fingerprint, not a password/credential hash — keyed with a fixed context +// label so it reads as a domain-separated digest rather than a bare password hash. function cacheKeyFor(apiKey: string): string { - return crypto.createHash("sha256").update(apiKey).digest("hex"); + return crypto.createHmac("sha256", "omniroute-cursor-session-cache-fingerprint-v1") + .update(apiKey) + .digest("hex"); } export function readJwtExpiryMs(token: string): number | null { diff --git a/tests/unit/antigravity-byop-account-rotation.test.ts b/tests/unit/antigravity-byop-account-rotation.test.ts index cba1318d16..e73b22c184 100644 --- a/tests/unit/antigravity-byop-account-rotation.test.ts +++ b/tests/unit/antigravity-byop-account-rotation.test.ts @@ -130,7 +130,7 @@ test("Antigravity BYOP 422 rotates to a sibling account and the request succeeds { status: 200, headers: { "Content-Type": "application/json" } } ); } - if (request.url.includes("cloudcode-pa.googleapis.com")) { + if (new URL(request.url).hostname === "cloudcode-pa.googleapis.com") { modelCalls.push({ token: (request.headers.get("authorization") || "").replace(/^Bearer\s+/i, ""), });