T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/gemini-image-runtime.mjs:122
- Finding
- Unvalidated Custom Gemini Endpoint Can Receive API Credentials and User Content<![CDATA[ ## Vulnerability Details **File Location**: `scripts/gemini-image-runtime.mjs:122-138`; supporting configuration guidance in `SKILL.md:17-19, 29-33, 57-59` **Vulnerability Type**: Unvalidated external service endpoint and sensitive-data redirection **Risk Level**: High ### Vulnerable Code ```js export function createGeminiImageClientFromEnv() { const apiKey = process.env.GEMINI_API_KEY; const model = process.env.GEMINI_MODEL_ID; const baseUrl = process.env.GEMINI_BASE_URL?.replace(/\/$/, ""); if (!apiKey) { throw new Error("Missing GEMINI_API_KEY in the environment"); } if (!model) { throw new Error("Missing GEMINI_MODEL_ID in the environment"); } return { ai: new GoogleGenAI({ apiKey, httpOptions: baseUrl ? { baseUrl } : undefined, }), model, }; } ``` The Skill documentation explicitly allows an arbitrary custom endpoint: ```json { "GEMINI_API_KEY": "sk-xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "GEMINI_MODEL_ID": "gemini-3.1-flash-image-preview", "GEMINI_BASE_URL": "https://custom-endpoint.com" } ``` ### Technical Analysis The value of `GEMINI_BASE_URL` is read directly from the environment and passed to the Google GenAI client without validating its protocol, hostname, port, or trust status. The same client is configured with `GEMINI_API_KEY` and is subsequently used to send generation prompts and inline image data. Consequently, a party capable of modifying the Skill environment can redirect requests to an attacker-controlled endpoint. The implementation does not require HTTPS, restrict destinations to approved Gemini hosts, or warn at runtime that the custom endpoint will receive sensitive request data and associated authentication material. For image-editing operations, local image bytes are base64-encoded and included in the request. This increases the exposure from prompt disclosure to disclosure of source images and potentially other local files accepted by the editing interface. ### ...[truncated 1427 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Use the official Gemini API endpoint by default and remove custom endpoint support unless it is operationally necessary. 2. If custom endpoints are required, enforce an explicit allowlist of trusted hostnames. 3. Require HTTPS and reject plaintext HTTP URLs. 4. Parse the URL with the platform URL parser and reject: - Embedded credentials. - Unexpected schemes. - Loopback, link-local, and private-network destinations unless explicitly approved. - Unapproved ports and IP-literal destinations. 5. Separate credentials by destination. Do not send the production Gemini API key to non-Google endpoints; require a distinct credential for each approved proxy. 6. Display an explicit warning or require affirmative configuration when a custom endpoint is active, stating that prompts and images will be transmitted to it. 7. Log only the normalized destination hostname, never the API key, prompt, or submitted file contents. 8. Add automated tests confirming that HTTP URLs and unapproved hosts are rejected. ]]>
