T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/assemblyai.mjs:22
- Finding
- Arbitrary API endpoint override exposes bearer credentials and sensitive media<![CDATA[ ## Vulnerability Details **File Location**: `scripts/assemblyai.mjs:22-28`, `scripts/assemblyai.mjs:582-589`, `scripts/assemblyai.mjs:769-783`, `scripts/assemblyai.mjs:860-880` **Vulnerability Type**: Unrestricted network destination with automatic credential forwarding **Risk Level**: High ### Vulnerable Code ```javascript // scripts/assemblyai.mjs:22-28 const command = String(positionals[0] || '').trim().toLowerCase(); const quiet = Boolean(flags.quiet); const sttBaseUrl = normaliseBaseUrl(flags['base-url'] ?? DEFAULT_STT_BASE_URL); const llmBaseUrl = normaliseBaseUrl(flags['llm-base-url'] ?? DEFAULT_LLM_BASE_URL_US); const pollMs = parsePositiveInt(flags['poll-ms'], 3000, '--poll-ms'); const timeoutMs = parsePositiveInt(flags['timeout-ms'], 1_800_000, '--timeout-ms'); const apiKey = String(flags['api-key'] ?? process.env.SKILLBOSS_API_KEY ?? ''); ``` ```javascript // scripts/assemblyai.mjs:582-589 function isHttpUrl(value) { return /^https?:\/\//i.test(String(value || '')); } function normaliseBaseUrl(raw) { return String(raw || '').replace(/\/+$/, ''); } ``` ```javascript // scripts/assemblyai.mjs:769-783 async function requestRaw(baseUrl, apiKey, relOrAbsUrl, { method = 'GET', headers = {}, body, quiet = false, retries = 4 } = {}) { const url = isHttpUrl(relOrAbsUrl) ? relOrAbsUrl : `${baseUrl}${String(relOrAbsUrl).startsWith('/') ? '' : '/'}${relOrAbsUrl}`; for (let attempt = 0; attempt <= retries; attempt += 1) { let res; try { res = await fetch(url, { method, headers: { ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}), ...headers, }, body, ``` ```javascript // scripts/assemblyai.mjs:860-880 async function uploadFile({ baseUrl, apiKey, filePath, quiet = false }) { const abs = path.resolve(expandHome(filePath)); const stat = await fsp.stat(abs); if (!stat.isFile()) throw new Error(`Not a file: ${abs}`); stderr(`Reading ${abs} (${stat.size} byt ...[truncated 3371 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Allowlist exact service origins** - Parse endpoints with `new URL()`. - Permit only explicitly approved HTTPS origins. - Compare `URL.origin` rather than using substring checks. 2. **Require TLS** - Reject all `http://` endpoints. - Reject URLs containing embedded credentials. - Reject malformed URLs and unexpected ports. 3. **Bind credentials to trusted origins** - Add the authorization header only after verifying the final destination against the allowlist. - Do not attach credentials to caller-supplied absolute URLs. - Disable redirects or validate every redirect destination before following it. 4. **Separate endpoint customization from normal operation** - Remove arbitrary endpoint flags from agent-facing workflows where possible. - If custom enterprise endpoints are necessary, require explicit configuration outside prompt-controlled command arguments and obtain user confirmation. 5. **Minimize sensitive-data exposure** - Display the destination origin before uploading. - Require confirmation when uploading local files to any non-default service. - Consider streaming uploads rather than retaining a second base64 copy of the entire recording in memory. 6. **Add security tests** - Verify that HTTP destinations are rejected. - Verify that unapproved domains never receive authorization headers. - Test deceptive hostnames, embedded credentials, alternate ports, and redirect behavior. ]]>
