T09 · Insecure Skill Coding Practices
- Location
lib/modelInvoker.ts:33- Finding
Unrestricted Model Endpoint Can Expose API Credentials and Prompt Content
- Content
View full analysis
Vulnerability Details
File Location:
lib/modelInvoker.ts:33-42, 76-96
Vulnerability Type: Unrestricted credential forwarding and sensitive prompt transmission
Risk Level: HighVulnerable Code
ts function resolveApiKey(options: InvokeModelOptions): string { const apiKey = options.apiKey ?? readEnv("MODEL_API_KEY") ?? readEnv("OPENAI_API_KEY"); if (!apiKey) { throw new Error("Missing API key. Set MODEL_API_KEY or OPENAI_API_KEY."); } return apiKey; } function resolveBaseUrl(options: InvokeModelOptions): string { return options.baseUrl ?? readEnv("MODEL_BASE_URL") ?? readEnv("OPENAI_BASE_URL") ?? DEFAULT_BASE_URL; }ts const response = await fetch(resolveBaseUrl(options), { method: "POST", signal: controller.signal, headers: { "Content-Type": "application/json", Authorization: `Bearer ${resolveApiKey(options)}`, ...(options.headers ?? {}), }, body: JSON.stringify({ model: options.model ?? readEnv("MODEL_NAME") ?? DEFAULT_MODEL, temperature: options.temperature ?? 0.7, max_tokens: options.maxTokens ?? 1600, messages: [ { role: "system", content: options.systemPrompt ?? "You are a helpful assistant that must return structured Chinese content.", }, { role: "user", content: prompt, }, ], }), });Technical Analysis
The model endpoint may be supplied through
options.baseUrl,MODEL_BASE_URL, orOPENAI_BASE_URL. The implementation does not validate the URL scheme, destination host, port, or network range, and it does not bind credentials to an approved provider.The request automatically attaches
MODEL_API_KEYorOPENAI_API_KEYas a bearer token and sends the complete generated prompt. That prompt includes user-provided content and bundled runtime configuration. If the endpoint is changed to an untrusted destination, ...[truncated 1925 chars]- Remediation
View remediation
Remediation Suggestions
- Require HTTPS for all credential-bearing model requests.
- Maintain an allowlist of approved model API hosts, or require explicit trusted-gateway registration before using a custom endpoint.
- Bind credentials to endpoints. In particular, send
OPENAI_API_KEYonly to explicitly approved OpenAI hosts. - Require a separate gateway-specific credential when a custom model endpoint is configured.
- Reject URLs containing embedded credentials and, unless explicitly required, reject loopback, link-local, private-network, and cloud metadata destinations.
- Validate redirect targets or disable redirects so an approved endpoint cannot redirect credentials to an untrusted host.
- Prevent
options.headersfrom overriding security-sensitive headers such asAuthorization,Host, andContent-Type. - Display a clear warning or fail closed when a custom endpoint is combined with a generic provider credential.
- Document that user content and runtime prompt configuration are transmitted to the selected model provider.
- Add automated tests for plaintext HTTP endpoints, unapproved hosts, redirects, private-network destinations, and cross-provider credential forwarding.
