T09 · Insecure Skill Coding Practices
Error
- Location
- index.js:13
- Finding
- RapidAPI credential is forwarded to arbitrary caller-controlled hosts by default<![CDATA[ ## Vulnerability Details **File Location**: `index.js:13-29`, `index.js:122-130`, `lib/engine.js:3-39`, `lib/engine.js:58-63`, `scripts/call.js:34-38`, `config.example.json:1-6` **Vulnerability Type**: Credential disclosure through unrestricted outbound requests **Risk Level**: Critical ### Vulnerable Code `index.js:13-29`: ```js const primaryEnv = options.primaryEnv || "RAPIDAPI_KEY"; const injectedEnv = options.env || {}; const config = options.config || {}; const rapidApiKey = options.apiKey || options.rapidApiKey || config.rapidApiKey || injectedEnv[primaryEnv] || process.env[primaryEnv]; const templatesDir = options.templatesDir || config.templatesDir || "./templates"; const allowNonRapidApiHosts = typeof options.allowNonRapidApiHosts === "boolean" ? options.allowNonRapidApiHosts : typeof config.allowNonRapidApiHosts === "boolean" ? config.allowNonRapidApiHosts : String(process.env.ALLOW_NON_RAPIDAPI_HOSTS || "true").toLowerCase() === "true"; ``` `index.js:122-130`: ```js async function callRapidApiDirect(input) { const meta = { host: input?.host || "unknown", path: input?.path || "unknown", method: input?.method || "unknown" }; try { return await callRapidApi( input, rapidApiKey, allowNonRapidApiHosts, timeoutMs ); ``` `lib/engine.js:3-39`: ```js export async function callRapidApi(input, rapidApiKey, allowNonRapidApiHosts, defaultTimeoutMs) { const method = (input.method || "GET").toUpperCase(); const meta = { host: input.host, path: input.path, method }; if (!input.host || String(input.host).includes("/") || String(input.host).includes(":")) { throw new HttpError(400, "Invalid host"); } if (!input.path || !String(input.path).startsWith("/")) { throw new HttpError(400, "Path must start with '/' "); } if (!allowNonRapidApiHosts) { const host = String(input.host); const isRapidApiHost = host.endsWith(".rapidapi.com") || host.endsWith(".p ...[truncated 3177 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Change the default to deny non-RapidAPI destinations: ```js String(process.env.ALLOW_NON_RAPIDAPI_HOSTS || "false").toLowerCase() === "true"; ``` 2. Change `config.example.json` to set `allowNonRapidApiHosts` to `false`. 3. Bind credential forwarding to an explicit allowlist. Do not add `X-RapidAPI-Key` unless the normalized destination is approved. 4. Prefer an exact, configurable host allowlist over broad suffix matching. 5. Separate generic HTTP calls from RapidAPI calls. Generic calls must not inherit the RapidAPI credential. 6. Restrict or remove the caller-controlled direct-call interface when it is unnecessary. 7. Disable automatic redirect following or manually validate every redirect target before forwarding sensitive headers. 8. Add tests proving that arbitrary hosts and redirected destinations never receive `X-RapidAPI-Key`. 9. Rotate any RapidAPI key used with the affected implementation if untrusted callers could invoke the direct-call interface. ]]>
