T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/repurpose.js:33
- Finding
- Arbitrary URL Fetching Enables Server-Side Request Forgery## Vulnerability Details **File Location**: `scripts/repurpose.js`, lines 33-43; invocation at lines 178-181 **Vulnerability Type**: Server-Side Request Forgery (SSRF) **Risk Level**: High ### Vulnerable Code ```js function httpGet(url) { return new Promise((resolve, reject) => { const u = new URL(url); const mod = u.protocol === 'https:' ? https : require('http'); mod.get(url, { headers: { 'User-Agent': 'Mozilla/5.0' } }, res => { let d = ''; res.on('data', c => d += c); res.on('end', () => resolve(d)); }).on('error', reject); }); } ``` The user-controlled URL reaches the function here: ```js if (args.url) { console.log(`🔗 Fetching ${args.url}...`); const html = await httpGet(args.url); content = extractText(html); } ``` ### Technical Analysis The `--url` command-line argument is passed directly to `httpGet`. The implementation does not apply a hostname allowlist, resolve and validate destination IP addresses, or reject loopback, private, link-local, and reserved network ranges. It also lacks connection and response timeouts and does not impose a response-size limit. Consequently, anyone able to control the command-line argument can instruct the process to issue HTTP requests from the host on which the skill runs. The request therefore inherits that host's network reachability and may access endpoints that are unavailable to an external attacker. The response is passed through `extractText` and subsequently submitted to OpenAI or Anthropic. This creates a potential secondary disclosure path in which information retrieved from an internal endpoint is transmitted to an external LLM service. ### Attack Path 1. An attacker or untrusted caller supplies a URL such as a loopback address, private network host, or cloud link-local metadata endpoint through `--url`. 2. `parseArgs` stores the value in `args.url`. 3. `main` passes the value directly to `httpGet` ...[truncated 1028 chars]
- Remediation
- ## Remediation Suggestions 1. Accept only explicitly supported protocols, preferably HTTPS. 2. Use an explicit allowlist of trusted source domains where operationally possible. 3. Resolve the hostname before connecting and reject every address in loopback, private, link-local, multicast, unspecified, and reserved ranges for both IPv4 and IPv6. 4. Ensure the validated IP is the address used for the connection to reduce DNS-rebinding and time-of-check/time-of-use risks. 5. If redirect support is later added, validate the protocol, hostname, and resolved destination again for every redirect. 6. Apply strict connection, read, and total-request timeouts. 7. Enforce a maximum response size while streaming rather than collecting an unlimited response before truncating extracted text. 8. Restrict accepted content types to expected textual formats. 9. Run the skill in a sandbox with outbound network restrictions that block internal and metadata networks. 10. Warn users before externally transmitting fetched content and avoid sending sensitive internal data to LLM providers.
