T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/run_youtube_subtitling.mjs:179
- Finding
- Bearer API Key Can Be Redirected to an Arbitrary or Plaintext Endpoint## Vulnerability Details **File Location**: `scripts/run_youtube_subtitling.mjs:179-205` **Vulnerability Type**: Unrestricted credential destination and insecure transport **Risk Level**: High ```javascript const apiBase = (process.env.FELO_API_BASE?.trim() || DEFAULT_API_BASE).replace(/\/$/, ''); const spinnerId = startSpinner(`Fetching subtitles ${videoCode}`); try { const params = new URLSearchParams({ video_code: videoCode }); if (args.language) params.set('language', args.language); if (args.withTime) params.set('with_time', 'true'); const url = `${apiBase}/v2/youtube/subtitling?${params.toString()}`; const payload = await fetchJson( url, { method: 'GET', headers: { Accept: 'application/json', Authorization: `Bearer ${apiKey}`, }, }, DEFAULT_TIMEOUT_MS ); ``` ### Technical Analysis The script obtains a sensitive Felo bearer credential from `FELO_API_KEY`, but allows its destination to be controlled through `FELO_API_BASE`. The override is accepted without validating its URL scheme or hostname. Consequently, the `Authorization` header is attached to requests sent to any endpoint selected through the environment variable. An attacker who can influence the launch environment could set the base URL to an attacker-controlled HTTPS server and directly collect the credential. The script also accepts an `http://` URL, allowing the credential and request metadata to traverse the network without transport encryption. A configurable endpoint may be useful for development or testing, but forwarding a production credential to an unrestricted destination exceeds the minimum privileges needed to fetch subtitles from the declared Felo API. ### Attack Path 1. An attacker gains the ability to influence the environment used to launch the Skill, such as through a wrapper script, compromised shell configuration, CI configuration, or agent runtime se ...[truncated 1148 chars]
- Remediation
- ## Remediation Suggestions - Remove `FELO_API_BASE` support if alternate service endpoints are not required for production operation. - If endpoint customization is required, parse the configured value with `URL` and require the `https:` protocol. - Maintain an explicit allowlist of trusted hosts, such as `openapi.felo.ai`, before attaching the authorization header. - Reject URLs containing embedded credentials, unexpected ports, fragments, or unapproved subdomains. - Construct the API URL with `new URL()` rather than string concatenation. - Separate production credentials from development credentials. Test endpoints must use restricted test keys. - Ensure redirects are either disabled or validated so that an approved endpoint cannot redirect an authenticated request to an untrusted host. - Document the endpoint override as security-sensitive and avoid inheriting it from untrusted execution environments. - Revoke and rotate any API key that may have been used while `FELO_API_BASE` pointed to an untrusted or plaintext endpoint. A hardened implementation should validate the destination before adding the credential: ```javascript const configuredBase = process.env.FELO_API_BASE?.trim() || DEFAULT_API_BASE; const baseUrl = new URL(configuredBase); if (baseUrl.protocol !== 'https:' || baseUrl.hostname !== 'openapi.felo.ai') { throw new Error('FELO_API_BASE must use the approved HTTPS endpoint'); } const url = new URL('/v2/youtube/subtitling', baseUrl); url.search = params.toString(); ```
