T09 · Insecure Skill Coding Practices
- Location
utils.js:12- Finding
Unrestricted Remote URL Fetching Enables Server-Side Request Forgery
- Content
View full analysis
{ const tempPath = path.join(os.tmpdir(), `trans_${crypto.randomBytes(4).toString('hex')}`); const res = await axios({ url, method: 'GET', responseType: 'arraybuffer', timeout: 30000 }); const buffer = Buffer.from(res.data); await fsPromises.writeFile(tempPath, buffer); let name = 'web_image.png'; try { name = path.basename(new URL(url).pathname) || name; } catch (e) { } return { buffer, tempPath, name }; } ``` The translation service's result URL is also fetched without validation: ```js const imageRes = await axios.get(resultUrl, { responseType: 'arraybuffer' }); await fsPromises.writeFile(localSavePath, Buffer.from(imageRes.data)); ``` ### Technical Analysis The skill treats every string beginning with `http://` or `https://` as a valid remote image. It does not resolve and inspect the destination address or reject loopback, private, link-local, reserved, multicast, or cloud metadata addresses. Axios follows redirects by default. Consequently, validating only the initial URL scheme would not be sufficient: an initially public endpoint could redirect the request to an internal address. The same issue affects `resultUrl`, which is obtained from the external translation API and then fetched by the local Agent process without checking its scheme, hostname, resolved address, or redirect chain. The request is made with the network privileges and reachability of the process running the skill. For user-supplied input URLs, downloaded response bytes are subsequently hashed and uploa ...[truncated 1997 chars]- Remediation
View remediation
