fix(security): sanitize error responses in OpenAI-compatible APIs
## Why The OpenAI-compatible API endpoints (`openai-http.ts`, `openresponses-http.ts`) were returning raw `String(err)` in error responses. This can leak sensitive internal information to HTTP clients: - Stack traces revealing code structure - File paths exposing server directory layout - Internal error messages from dependencies This is the same class of vulnerability that was fixed in #2387 for `server-http.ts`, but these OpenAI-compatible endpoints were missed. ## What Replace `String(err)` with safe error messages: - **500 errors (api_error)**: Return generic "Internal server error" - **400 errors (invalid_request_error)**: Return `err.message` only (no stack trace), with fallback to "Invalid request" ## Changes - `src/gateway/openai-http.ts`: 2 catch blocks sanitized - `src/gateway/openresponses-http.ts`: 4 catch blocks sanitized
This commit is contained in:
parent
6af205a13a
commit
8d46b92e30
@ -239,9 +239,9 @@ export async function handleOpenAiHttpRequest(
|
||||
],
|
||||
usage: { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 },
|
||||
});
|
||||
} catch (err) {
|
||||
} catch {
|
||||
sendJson(res, 500, {
|
||||
error: { message: String(err), type: "api_error" },
|
||||
error: { message: "Internal server error", type: "api_error" },
|
||||
});
|
||||
}
|
||||
return true;
|
||||
@ -361,7 +361,7 @@ export async function handleOpenAiHttpRequest(
|
||||
],
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
} catch {
|
||||
if (closed) return;
|
||||
writeSse(res, {
|
||||
id: runId,
|
||||
@ -371,7 +371,7 @@ export async function handleOpenAiHttpRequest(
|
||||
choices: [
|
||||
{
|
||||
index: 0,
|
||||
delta: { content: `Error: ${String(err)}` },
|
||||
delta: { content: "Error: Internal server error" },
|
||||
finish_reason: "stop",
|
||||
},
|
||||
],
|
||||
|
||||
@ -435,7 +435,7 @@ export async function handleOpenResponsesHttpRequest(
|
||||
}
|
||||
} catch (err) {
|
||||
sendJson(res, 400, {
|
||||
error: { message: String(err), type: "invalid_request_error" },
|
||||
error: { message: err instanceof Error ? err.message : "Invalid request", type: "invalid_request_error" },
|
||||
});
|
||||
return true;
|
||||
}
|
||||
@ -452,7 +452,7 @@ export async function handleOpenResponsesHttpRequest(
|
||||
toolChoicePrompt = toolChoiceResult.extraSystemPrompt;
|
||||
} catch (err) {
|
||||
sendJson(res, 400, {
|
||||
error: { message: String(err), type: "invalid_request_error" },
|
||||
error: { message: err instanceof Error ? err.message : "Invalid request", type: "invalid_request_error" },
|
||||
});
|
||||
return true;
|
||||
}
|
||||
@ -565,13 +565,13 @@ export async function handleOpenResponsesHttpRequest(
|
||||
});
|
||||
|
||||
sendJson(res, 200, response);
|
||||
} catch (err) {
|
||||
} catch {
|
||||
const response = createResponseResource({
|
||||
id: responseId,
|
||||
model,
|
||||
status: "failed",
|
||||
output: [],
|
||||
error: { code: "api_error", message: String(err) },
|
||||
error: { code: "api_error", message: "Internal server error" },
|
||||
});
|
||||
sendJson(res, 500, response);
|
||||
}
|
||||
@ -844,7 +844,7 @@ export async function handleOpenResponsesHttpRequest(
|
||||
delta: content,
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
} catch {
|
||||
if (closed) return;
|
||||
|
||||
finalUsage = finalUsage ?? createEmptyUsage();
|
||||
@ -853,7 +853,7 @@ export async function handleOpenResponsesHttpRequest(
|
||||
model,
|
||||
status: "failed",
|
||||
output: [],
|
||||
error: { code: "api_error", message: String(err) },
|
||||
error: { code: "api_error", message: "Internal server error" },
|
||||
usage: finalUsage,
|
||||
});
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user