T09 · Insecure Skill Coding Practices
Error
- Location
- skill.js:22
- Finding
- Unrestricted API endpoint receives user content and bearer credentials<![CDATA[ ## Vulnerability Details **File Location**: `skill.js`, lines 22–32 **Vulnerability Type**: Unrestricted outbound transmission of sensitive data and credentials **Risk Level**: High ### Vulnerable Code ```javascript const res = await fetch(`${API_BASE}/chat/completions`, { method: "POST", headers: { "Authorization": "Bearer " + API_KEY, "Content-Type": "application/json" }, body: JSON.stringify({ model: MODEL_NAME, messages: [{ role: "user", content: prompt }] }) }); ``` ### Technical Analysis The Skill sends an outbound request to a URL derived directly from the environment-controlled `API_BASE` value. It does not validate the URL scheme, destination hostname, port, resolved IP address, or whether the endpoint belongs to an approved model provider. The request contains two sensitive elements: 1. The `Authorization` header carries `API_KEY` as a bearer credential. 2. The request body carries `prompt`, which incorporates the user-provided novel title, full novel text, and style tag. A remote model call is consistent with the declared functionality, but allowing an arbitrary destination exceeds the minimum privileges required. The Skill only needs access to a specific trusted model provider, not unrestricted network destinations. If `API_BASE` is maliciously configured or accidentally points to an untrusted service, both the submitted content and bearer credential are disclosed. Because non-HTTPS schemes are not rejected, the current implementation may also send the credential and content without transport encryption. Depending on the execution environment and network controls, an unrestricted destination may additionally enable server-side requests to internal or loopback services. ### Attack Path 1. An attacker gains control over the Skill's `API_BASE` configuration, or convinces an operator to use an attacker-controlled endpoint. 2. The attacker sets `API_BASE` to a server they operate, a plaintext HTTP endpoint, o ...[truncated 1279 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Replace arbitrary endpoint support with an explicit allowlist of trusted HTTPS origins. 2. Parse `API_BASE` with the standard `URL` API and reject: - Any scheme other than HTTPS. - URLs containing embedded credentials. - Unexpected ports. - Loopback, link-local, private, multicast, and otherwise reserved IP destinations. - Hostnames or resolved addresses outside the approved provider list. 3. Pin the expected API path instead of allowing configuration to influence the entire destination. 4. Disable redirects, or validate every redirect target before following it. 5. Use a provider-scoped API key with the minimum required permissions, strict spending limits, and routine rotation. 6. Keep model credentials isolated per environment and per Skill where possible. 7. Clearly disclose that the title and full novel text are transmitted to an external model provider. 8. Apply request timeouts, response-size limits, and controlled error handling. 9. Avoid logging authorization headers, complete prompts, or raw model responses. 10. If arbitrary providers must be supported, require explicit administrative approval and enforce equivalent destination and TLS validation for each configured provider. ]]>
