Files
OmniRoute/open-sse/config/oci.ts
diegosouzapw 9e198184a7 fix(security): resolve 14 CodeQL code scanning alerts
- Replace polynomial regex /\/+$/ with loop-based stripTrailingSlashes()
  across 8 enterprise provider configs (azure-openai, azureAi, bedrock,
  datarobot, oci, sap, watsonx, audioSpeech) — fixes js/polynomial-redos

- Add prototype-pollution denylist guard in usageHistory.ts to reject
  __proto__/constructor/prototype as model keys — fixes
  js/prototype-polluting-assignment (#167, #168)

- Suppress 3 false-positive js/insufficient-password-hash alerts in
  chatgpt-web.ts and builtins.ts where SHA-256 is used for cache-key
  derivation, not password storage (#176, #177, #178)

- Add stripTrailingSlashes unit tests with ReDoS regression check
2026-04-27 20:00:10 -03:00

49 lines
1.4 KiB
TypeScript

import { stripTrailingSlashes } from "../utils/urlSanitize.ts";
export const OCI_DEFAULT_BASE_URL =
"https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/openai/v1";
function normalizeBaseUrl(value: string | null | undefined): string {
return stripTrailingSlashes((value || "").trim());
}
export function normalizeOciBaseUrl(value: string | null | undefined): string {
const normalized = normalizeBaseUrl(value || OCI_DEFAULT_BASE_URL);
if (!normalized) return OCI_DEFAULT_BASE_URL;
const stripped = normalized.replace(/\/(?:chat\/completions|responses|models)$/i, "");
if (stripped.endsWith("/openai/v1")) {
return stripped;
}
if (stripped.endsWith("/openai")) {
return `${stripped}/v1`;
}
try {
const parsed = new URL(stripped);
if (!parsed.pathname || parsed.pathname === "/") {
parsed.pathname = "/openai/v1";
} else if (parsed.pathname.endsWith("/openai")) {
parsed.pathname = `${parsed.pathname}/v1`;
}
parsed.search = "";
parsed.hash = "";
return stripTrailingSlashes(parsed.toString());
} catch {
return stripped;
}
}
export function buildOciChatUrl(
value: string | null | undefined,
apiType: "chat" | "responses" = "chat"
): string {
return `${normalizeOciBaseUrl(value)}/${apiType === "responses" ? "responses" : "chat/completions"}`;
}
export function buildOciModelsUrl(value: string | null | undefined): string {
return `${normalizeOciBaseUrl(value)}/models`;
}