mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-31 12:22:14 +03:00
fix(security): clear CodeQL high alerts surfaced on the v3.8.11 release PR diff
CodeQL flagged 7 high alerts in code the cycle touched (the large release-PR diff
re-surfaces them). Resolved at the source — no dismissals:
- fix(images): resolveImageBaseUrl trimmed trailing slashes with `/\/+$/`, a
polynomial-ReDoS pattern (js/polynomial-redos) on the configured node base URL.
Replace it with a non-backtracking endsWith/slice loop.
- test(oauth): pin the Anthropic OAuth host with exact-equality asserts and a
parsed-hostname negative check instead of substring `.includes()`
(js/incomplete-url-substring-sanitization). The exact-equality assertions were
already present, so coverage is unchanged.
- test(images): drop the redundant `!includes("generativelanguage.googleapis.com")`
assert — the exact-equality assert on the resolved URL already guarantees it.
This commit is contained in:
@@ -131,7 +131,10 @@ export function resolveImageBaseUrl(
|
||||
// points at the requested OpenAI image path, and rewrite one that points at the other
|
||||
// image endpoint (e.g. `.../images/generations` requested for edits) (#3214/#3215).
|
||||
const suffix = `/images/${endpoint}`;
|
||||
const normalized = nodeBaseUrl.replace(/\/+$/, "");
|
||||
// Trim trailing slashes without a backtracking-prone regex (`/\/+$/` is a
|
||||
// polynomial-ReDoS pattern on long runs of "/" — CodeQL js/polynomial-redos).
|
||||
let normalized = nodeBaseUrl;
|
||||
while (normalized.endsWith("/")) normalized = normalized.slice(0, -1);
|
||||
if (normalized.endsWith(suffix)) return normalized;
|
||||
const stripped = normalized.replace(/\/images\/(?:generations|edits)$/, "");
|
||||
return `${stripped}${suffix}`;
|
||||
|
||||
@@ -4,23 +4,15 @@ import { CLAUDE_CONFIG } from "@/lib/oauth/constants/oauth.ts";
|
||||
import { OAUTH_ENDPOINTS } from "@omniroute/open-sse/config/constants.ts";
|
||||
import { REGISTRY } from "@omniroute/open-sse/config/providerRegistry.ts";
|
||||
|
||||
// Exact-equality assertions (not substring `.includes`) so the host is pinned
|
||||
// precisely — a substring check would also pass for e.g. `api.anthropic.com.evil`
|
||||
// (CodeQL js/incomplete-url-substring-sanitization).
|
||||
|
||||
test("CLAUDE_CONFIG.tokenUrl uses api.anthropic.com (not console.anthropic.com)", () => {
|
||||
assert.ok(
|
||||
CLAUDE_CONFIG.tokenUrl.includes("api.anthropic.com"),
|
||||
`Expected api.anthropic.com but got ${CLAUDE_CONFIG.tokenUrl}`
|
||||
);
|
||||
assert.equal(CLAUDE_CONFIG.tokenUrl, "https://api.anthropic.com/v1/oauth/token");
|
||||
});
|
||||
|
||||
test("OAUTH_ENDPOINTS.anthropic uses api.anthropic.com for token and auth", () => {
|
||||
assert.ok(
|
||||
OAUTH_ENDPOINTS.anthropic.token.includes("api.anthropic.com"),
|
||||
`Expected api.anthropic.com but got ${OAUTH_ENDPOINTS.anthropic.token}`
|
||||
);
|
||||
assert.ok(
|
||||
OAUTH_ENDPOINTS.anthropic.auth.includes("api.anthropic.com"),
|
||||
`Expected api.anthropic.com but got ${OAUTH_ENDPOINTS.anthropic.auth}`
|
||||
);
|
||||
assert.equal(OAUTH_ENDPOINTS.anthropic.token, "https://api.anthropic.com/v1/oauth/token");
|
||||
assert.equal(OAUTH_ENDPOINTS.anthropic.auth, "https://api.anthropic.com/v1/oauth/authorize");
|
||||
});
|
||||
@@ -28,10 +20,6 @@ test("OAUTH_ENDPOINTS.anthropic uses api.anthropic.com for token and auth", () =
|
||||
test("Provider registry claude oauth.tokenUrl uses api.anthropic.com", () => {
|
||||
const claude = REGISTRY.claude;
|
||||
assert.ok(claude, "claude provider should exist in registry");
|
||||
assert.ok(
|
||||
claude.oauth?.tokenUrl?.includes("api.anthropic.com"),
|
||||
`Expected api.anthropic.com but got ${claude.oauth?.tokenUrl}`
|
||||
);
|
||||
assert.equal(claude.oauth.tokenUrl, "https://api.anthropic.com/v1/oauth/token");
|
||||
});
|
||||
|
||||
@@ -41,12 +29,13 @@ test("No console.anthropic.com remains in OAuth constants or registry", () => {
|
||||
OAUTH_ENDPOINTS.anthropic.token,
|
||||
OAUTH_ENDPOINTS.anthropic.auth,
|
||||
REGISTRY.claude?.oauth?.tokenUrl,
|
||||
].filter(Boolean);
|
||||
].filter(Boolean) as string[];
|
||||
for (const url of allUrls) {
|
||||
assert.equal(
|
||||
url.includes("console.anthropic.com"),
|
||||
false,
|
||||
`Found console.anthropic.com in ${url}`
|
||||
// Compare the parsed hostname, not a substring, so the check is exact.
|
||||
assert.notEqual(
|
||||
new URL(url).hostname,
|
||||
"console.anthropic.com",
|
||||
`Found console.anthropic.com host in ${url}`
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -14,12 +14,9 @@ test("#3205: custom node baseUrl from providerSpecificData is used (not Gemini f
|
||||
resolved.startsWith("https://example.com/"),
|
||||
`expected resolved URL to point to example.com, got: ${resolved}`
|
||||
);
|
||||
assert.ok(
|
||||
!resolved.includes("generativelanguage.googleapis.com"),
|
||||
`resolved URL must not fall back to the Gemini endpoint, got: ${resolved}`
|
||||
);
|
||||
// A node configured as https://example.com/v1 should yield the OpenAI-compatible
|
||||
// images path appended.
|
||||
// The exact-equality assertion below already guarantees the Gemini fallback
|
||||
// was not used (a substring `.includes` check trips CodeQL
|
||||
// js/incomplete-url-substring-sanitization and is redundant here).
|
||||
assert.equal(resolved, "https://example.com/v1/images/generations");
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user