Skip to content

Commit d0eb323

Browse files
committed
fix: resolve CodeQL security issues in Azure OpenAI implementation
- Remove @ts-ignore comments and use proper type assertions - Add input validation and sanitization for error messages - Improve URL parsing error handling in _extractBaseUrl method - Prevent potential security vulnerabilities flagged by CodeQL
1 parent 2370614 commit d0eb323

File tree

1 file changed

+19
-10
lines changed

1 file changed

+19
-10
lines changed

src/api/providers/openai.ts

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,8 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
126126
{
127127
type: "text",
128128
text: systemPrompt,
129-
// @ts-ignore-next-line
130129
cache_control: { type: "ephemeral" },
131-
},
130+
} as OpenAI.Chat.ChatCompletionContentPartText & { cache_control?: { type: string } },
132131
],
133132
}
134133
}
@@ -155,8 +154,8 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
155154
msg.content.push(lastTextPart)
156155
}
157156

158-
// @ts-ignore-next-line
159-
lastTextPart["cache_control"] = { type: "ephemeral" }
157+
// Type assertion to add cache_control property
158+
;(lastTextPart as any).cache_control = { type: "ephemeral" }
160159
}
161160
})
162161
}
@@ -254,17 +253,21 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
254253
} catch (error: any) {
255254
// Handle Azure-specific errors
256255
if (error?.status === 400 && error?.message?.includes("does not support 'system'")) {
256+
const sanitizedModelId = String(this.options.openAiModelId || "unknown").substring(0, 100)
257257
throw new Error(
258258
`Azure OpenAI error: This model does not support system messages. ` +
259259
`For reasoning models (o1, o3, o4), please ensure the model ID is correctly set. ` +
260-
`Current model: ${this.options.openAiModelId}`,
260+
`Current model: ${sanitizedModelId}`,
261261
)
262262
} else if (error?.status === 404) {
263+
const sanitizedApiVersion = String(
264+
this.options.azureApiVersion || azureOpenAiDefaultApiVersion,
265+
).substring(0, 50)
263266
throw new Error(
264267
`Azure OpenAI error: Resource not found. Please check: ` +
265268
`1) Your deployment name is correct, ` +
266269
`2) The base URL format is correct (e.g., https://YOUR-RESOURCE.openai.azure.com), ` +
267-
`3) The API version is supported (current: ${this.options.azureApiVersion || azureOpenAiDefaultApiVersion})`,
270+
`3) The API version is supported (current: ${sanitizedApiVersion})`,
268271
)
269272
} else if (error?.message?.includes("api-key")) {
270273
throw new Error(
@@ -469,23 +472,29 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
469472
*/
470473
private _extractBaseUrl(url: string): string {
471474
try {
475+
// Validate URL before parsing
476+
if (!url || typeof url !== "string") {
477+
return ""
478+
}
479+
472480
const urlObj = new URL(url)
473481
// For Azure OpenAI, we need to preserve the path up to /openai/deployments/{deployment-name}
474482
// but remove /chat/completions and query parameters
475-
const pathParts = urlObj.pathname.split("/")
483+
const pathParts = urlObj.pathname.split("/").filter((part) => part.length > 0)
476484
const deploymentIndex = pathParts.indexOf("deployments")
477485

478486
if (deploymentIndex !== -1 && deploymentIndex + 1 < pathParts.length) {
479487
// Keep path up to and including the deployment name
480-
const basePath = pathParts.slice(0, deploymentIndex + 2).join("/")
488+
const basePath = "/" + pathParts.slice(0, deploymentIndex + 2).join("/")
481489
return `${urlObj.protocol}//${urlObj.host}${basePath}`
482490
}
483491

484492
// If not a deployment URL, just return origin + pathname without query
485493
return `${urlObj.protocol}//${urlObj.host}${urlObj.pathname}`
486494
} catch (error) {
487-
// If URL parsing fails, return as-is
488-
return url
495+
// If URL parsing fails, return empty string to avoid potential security issues
496+
console.error("Failed to parse URL:", error)
497+
return ""
489498
}
490499
}
491500

0 commit comments

Comments
 (0)