T09 · Insecure Skill Coding Practices
- Location
scripts/api-client.mjs:14- Finding
Bearer API Key Can Be Transmitted Over Plaintext HTTP
- Content
View full analysis
Vulnerability Details
File Location:
scripts/api-client.mjs:14-26, 71-79
Vulnerability Type: Insecure transport of authentication credentials
Risk Level: HighVulnerable code:
js export function normalizeBaseUrl(value) { const baseUrl = String(value || '').trim().replace(/\/+$/, ''); if (!baseUrl) throw new Error('base_url is required. Configure credentials before calling the API.'); let parsed; try { parsed = new URL(baseUrl); } catch { throw new Error('base_url must be an absolute http(s) URL.'); } if (!['http:', 'https:'].includes(parsed.protocol)) throw new Error('base_url must use http or https.'); return baseUrl; }js export async function request(relativePath, options = {}, configuration = loadConfiguration()) { const response = await fetch(endpoint(relativePath, configuration), { ...options, headers: { Accept: 'application/json', Authorization: `Bearer ${configuration.apiKey}`, ...(options.headers || {}), }, });Technical Analysis
normalizeBaseUrl()accepts both HTTP and HTTPS tenant origins. Therequest()function subsequently attaches the persistent API key to every request as a Bearer credential.When an ordinary
http://origin is configured, the Authorization header, request body, and response are transmitted without transport encryption or server authentication. This contradicts the HTTPS-only network boundary declared inmanifest.yaml.The issue affects discovery, model and application calls, task polling, and local-media uploads because all of them use the same request helper. The credential file's restrictive filesystem permissions do not protect a key once it is sent over an unencrypted connection.
Attack Path
- An attacker persuades a user to configure an
http://tenant origin, modifies the local configuration, or intercepts access to a legitimate HTTP depl ...[truncated 957 chars]
- An attacker persuades a user to configure an
- Remediation
View remediation
Remediation Suggestions
-
Reject all non-HTTPS tenant origins by default:
js if (parsed.protocol !== 'https:') { throw new Error('base_url must use HTTPS.'); } -
If local development requires HTTP, permit it only for explicit loopback hosts such as
127.0.0.1,::1, orlocalhost, and require a clearly named development-only opt-in. -
Ensure the normalized URL does not contain username or password URL components.
-
Add automated tests confirming that public and private-network HTTP URLs are rejected.
-
Add an integration test verifying that authorization headers are sent only to approved HTTPS origins.
-
Keep the manifest and runtime enforcement consistent; do not rely solely on declarative
httpsOutboundmetadata.
-
