T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/main.mjs:6
- Finding
- Unrestricted API Base URL Override Enables Credential and Text Disclosure## Vulnerability Details **File Location**: `scripts/main.mjs`, lines 6 and 43–50 **Vulnerability Type**: Unvalidated destination override causing sensitive-data exfiltration **Risk Level**: High ### Vulnerable Code ```js const API_BASE = process.env.CRAZYROUTER_BASE_URL || "https://crazyrouter.com/v1"; ``` ```js const apiKey = getApiKey(); console.error(`Model: ${args.model}, Voice: ${args.voice}, Speed: ${args.speed}x`); const response = await fetch(`${API_BASE}/audio/speech`, { method: "POST", headers: { "Authorization": `Bearer ${apiKey}`, "Content-Type": "application/json" }, body: JSON.stringify({ model: args.model, input: text, voice: args.voice, speed: args.speed, response_format: args.format }), }); ``` ### Technical Analysis The script permits the `CRAZYROUTER_BASE_URL` environment variable to replace the trusted Crazyrouter API origin without validating the URL scheme, hostname, port, or destination. It subsequently sends both the `CRAZYROUTER_API_KEY` bearer credential and user-provided text to the selected endpoint. An attacker who can influence the process environment can set this variable to an attacker-controlled HTTP or HTTPS server. The next invocation then discloses the authorization header and TTS input to that server. Because arbitrary destinations are accepted, the behavior may also permit requests to local services or cloud metadata addresses, although response handling and the fixed `/audio/speech` suffix may limit practical exploitation of particular internal endpoints. ### Attack Path 1. The victim has a valid `CRAZYROUTER_API_KEY` in the execution environment. 2. An attacker gains the ability to influence the Skill's environment, launcher configuration, shell profile, or orchestration settings. 3. The attacker sets `CRAZYROUTER_BASE_URL` to an endpoint under their control. 4. The victim invokes the Skill with `--text` or `--input`. 5. The script sends a POST request to the attacker-selected endpoint. 6. The request expos ...[truncated 758 chars]
- Remediation
- ## Remediation Suggestions - Remove `CRAZYROUTER_BASE_URL` if endpoint customization is not an explicit requirement. - If customization is required, parse the value with `new URL()` and enforce: - The `https:` scheme. - An explicit allowlist of trusted Crazyrouter hostnames. - Expected ports and path prefixes. - Rejection of embedded credentials, IP literals, loopback addresses, private networks, link-local destinations, and cloud metadata endpoints. - Before attaching the bearer token, compare the final request origin against the approved origin; fail closed on any mismatch. - Avoid following redirects to untrusted origins, or manually validate every redirect destination before resending sensitive headers. - Document any supported endpoint override in `SKILL.md`, including its trust and security requirements. - Add automated tests confirming that HTTP URLs, unapproved domains, local addresses, metadata addresses, and redirect-based origin changes are rejected.
