T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/generate-slides.js:137
- Finding
- Replicate API Token Disclosure Through an Unvalidated Polling URL<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate-slides.js`, lines 137-139 **Vulnerability Type**: Credential disclosure through a response-controlled URL **Risk Level**: High ### Vulnerable Code ```javascript const pollRes = await fetch(prediction.urls.get, { headers: { 'Authorization': `Token ${apiKey}` } }); prediction = await pollRes.json(); ``` ### Technical Analysis The script obtains `prediction.urls.get` from the Replicate API response and uses it directly as the destination of an authenticated request. It does not verify: - That the URL uses HTTPS. - That the hostname belongs to Replicate. - That the URL does not resolve to a private or loopback address. - That redirects remain within an approved Replicate domain. The request includes the user's Replicate API token in the `Authorization` header. Consequently, a compromised, intercepted, or malformed API response could supply an attacker-controlled polling URL and cause the script to transmit the token to that endpoint. Although the initial prediction request is sent to a hard-coded Replicate HTTPS endpoint, treating a response-provided URL as trusted creates a credential-forwarding vulnerability. ### Attack Path 1. The user configures the Skill with a valid Replicate API token. 2. The script submits an image-generation request to Replicate. 3. An attacker capable of compromising or influencing the returned prediction object supplies an attacker-controlled value in `prediction.urls.get`. 4. The script calls the supplied URL without validating its origin. 5. The request includes `Authorization: Token <user-token>`. 6. The attacker records the token and uses it to submit predictions or consume the victim's Replicate account quota. ### Impact Assessment Successful exploitation exposes the Replicate API token. An attacker could obtain the privileges assigned to that token, including submitting paid inference jobs, accessing associated API resources, exhausting quotas, or c ...[truncated 190 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Parse `prediction.urls.get` with the standard `URL` class before using it. - Require the `https:` protocol. - Maintain an explicit allowlist of documented Replicate API hostnames. - Reject URLs containing embedded credentials or unexpected ports. - Disable automatic redirects where possible, or validate every redirect target before forwarding credentials. - Never attach the Replicate token to a URL that has not passed origin validation. - Consider constructing the polling endpoint locally from a validated prediction identifier instead of trusting a complete URL from the response. Example hardening pattern: ```javascript function validateReplicateUrl(value) { const url = new URL(value); const allowedHosts = new Set(['api.replicate.com']); if (url.protocol !== 'https:' || !allowedHosts.has(url.hostname)) { throw new Error('Untrusted Replicate polling URL'); } return url.toString(); } const pollingUrl = validateReplicateUrl(prediction.urls.get); const pollRes = await fetch(pollingUrl, { redirect: 'error', headers: { Authorization: `Token ${apiKey}` } }); ``` ]]>
