Files
OmniRoute/open-sse/executors/azure-openai.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

43 lines
1.5 KiB
TypeScript

import { DefaultExecutor } from "./default.ts";
import { stripTrailingSlashes } from "../utils/urlSanitize.ts";
const DEFAULT_API_VERSION = "2024-12-01-preview";
function normalizeAzureBaseUrl(rawBaseUrl?: string | null): string {
const normalized = stripTrailingSlashes((rawBaseUrl || "").trim());
if (!normalized) return "";
return normalized
.replace(/\/openai$/i, "")
.replace(/\/openai\/deployments\/[^/]+\/chat\/completions[^/]*$/i, "");
}
export class AzureOpenAIExecutor extends DefaultExecutor {
constructor() {
super("azure-openai");
}
buildUrl(model: string, stream: boolean, urlIndex = 0, credentials: any = null) {
void urlIndex;
const providerSpecificData = credentials?.providerSpecificData || {};
const baseUrl = normalizeAzureBaseUrl(providerSpecificData.baseUrl || this.config.baseUrl);
const apiVersion =
typeof providerSpecificData.apiVersion === "string" && providerSpecificData.apiVersion.trim()
? providerSpecificData.apiVersion.trim()
: DEFAULT_API_VERSION;
return `${baseUrl}/openai/deployments/${encodeURIComponent(model)}/chat/completions?api-version=${encodeURIComponent(apiVersion)}`;
}
buildHeaders(credentials: any, stream = true) {
const apiKey = credentials?.apiKey || credentials?.accessToken || "";
const headers: Record<string, string> = {
"Content-Type": "application/json",
"api-key": apiKey,
};
headers.Accept = stream ? "text/event-stream" : "application/json";
return headers;
}
}