T09 · Insecure Skill Coding Practices
Error
- Location
- skill.js:4
- Finding
- Bearer Credential Transmission to an Unrestricted Configurable Endpoint## Vulnerability Details **File Location**: `skill.js`, lines 4–17 **Vulnerability Type**: Unrestricted credential-bearing network request **Risk Level**: High ### Vulnerable Code ```javascript const API_KEY = env.API_KEY; const API_BASE = env.API_BASE; const MODEL_NAME = env.MODEL_NAME; const res = await fetch(`${API_BASE}/img2video`, { method: "POST", headers: { "Authorization": "Bearer " + API_KEY, "Content-Type": "application/json" }, body: JSON.stringify({ model: MODEL_NAME, image_url: image_url }) }); ``` ### Technical Analysis The Skill constructs its request destination directly from the configurable `API_BASE` value and transmits `API_KEY` in the `Authorization` header. It does not parse or validate the URL, require HTTPS, restrict the destination to approved provider hosts, reject embedded credentials, or constrain ports. Although an outbound request is necessary for the declared image-to-video functionality, sending a secret to an arbitrary configured destination exceeds safe least-privilege boundaries. A malicious or incorrectly configured `API_BASE` can direct the request to an attacker-controlled server. A plaintext HTTP endpoint can also expose the credential and submitted data to network interception. The request additionally discloses `MODEL_NAME` and the user-supplied `image_url` to the selected endpoint. Depending on the URL, the image address may itself contain sensitive identifiers, signed query parameters, or access tokens. ### Attack Path 1. An attacker, compromised deployment process, or configuration error changes `API_BASE` to an attacker-controlled URL or a plaintext HTTP endpoint. 2. A user invokes the Skill with an `image_url`. 3. The Skill appends `/img2video` to the unvalidated base URL. 4. It sends `Authorization: Bearer <API_KEY>`, `MODEL_NAME`, and `image_url` to that endpoint. 5. The attacker captures the API credential and subm ...[truncated 779 chars]
- Remediation
- ## Remediation Suggestions 1. Parse `API_BASE` with `new URL()` before constructing the request. 2. Require the `https:` protocol and reject plaintext HTTP. 3. Enforce an explicit allowlist of approved image-to-video provider hostnames rather than accepting an arbitrary network destination. 4. Reject URLs containing embedded usernames or passwords, unexpected ports, fragments, or unsupported schemes. 5. Build the endpoint using URL APIs rather than direct string interpolation. 6. Scope the API key to only the required image-to-video operation, with minimal quotas and no unrelated resource permissions. 7. Use separate credentials for different providers or environments and rotate the key if it may have been exposed. 8. Validate `image_url` according to provider requirements and warn users not to submit URLs containing reusable credentials or sensitive signed parameters. 9. Fail closed when endpoint validation fails and avoid including secrets in error messages or logs. Example hardening pattern: ```javascript const approvedHosts = new Set(["api.example-provider.com"]); const base = new URL(env.API_BASE); if ( base.protocol !== "https:" || !approvedHosts.has(base.hostname) || base.username || base.password || (base.port && base.port !== "443") ) { throw new Error("Invalid API endpoint configuration"); } const endpoint = new URL("/img2video", base); ```
