T09 · Insecure Skill Coding Practices
- Location
scripts/fetch.mjs:59- Finding
Unrestricted URL Fetching Enables Server-Side Request Forgery
- Content
View full analysis
Vulnerability Details
File Location:
scripts/fetch.mjs, lines 59–81
Vulnerability Type: Server-Side Request Forgery (SSRF)
Risk Level: HighVulnerable Code
js // Validate URLs for (const url of urls) { try { new URL(url); } catch { console.error(`Invalid URL: ${url}`); process.exit(1); } } async function fetchUrl(url, customHeaders = {}) { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), timeout); try { const resp = await fetch(url, { headers: { "User-Agent": new UserAgent().toString(), ...customHeaders, }, signal: controller.signal, });Technical Analysis
The script accepts user-controlled URLs and verifies only that each value can be parsed by the JavaScript
URLconstructor. This is syntactic validation and does not establish whether the destination is safe.There are no controls preventing requests to loopback, private, link-local, multicast, or other reserved network ranges. The code also does not constrain the allowed protocols, resolve and validate hostnames before connecting, reject embedded credentials, or validate redirect destinations.
Node.js
fetchfollows HTTP redirects by default. Therefore, even if validation of the initial hostname were later introduced, an attacker-controlled public endpoint could redirect the request to an internal address unless every redirect target is separately validated.The caller can also supply arbitrary request headers. This can increase the impact against internal services that rely on special headers, bearer tokens supplied by the caller, virtual-host routing, or other header-based access controls.
Attack Path
- An attacker causes the skill to be invoked with a URL targeting an internal resource, such as
http://127.0.0.1:<port>/, a private-network host, or a link-local cloud metadat ...[truncated 1638 chars]
- An attacker causes the skill to be invoked with a URL targeting an internal resource, such as
- Remediation
View remediation
Remediation Suggestions
- Permit only explicitly required protocols, normally
https:and, only where necessary,http:. Reject all other URL schemes. - Reject URLs containing embedded usernames or passwords.
- Prefer an explicit allowlist of approved domains and ports when the expected destinations are known.
- Resolve destination hostnames before connecting and reject every loopback, private, link-local, multicast, unspecified, documentation, and reserved IPv4 or IPv6 address.
- Protect against DNS rebinding by ensuring the validated address is the address used for the connection, or by enforcing equivalent destination controls at the network layer.
- Disable automatic redirects with
redirect: "manual"or validate the scheme, hostname, port, and resolved address of every redirect target before following it. - Apply the same validation to every URL in a multi-URL request.
- Restrict caller-controlled headers to a small allowlist. Explicitly reject sensitive or routing-relevant headers unless they are required, including
Authorization,Cookie,Host, forwarding headers, and proxy-related headers. - Enforce egress firewall or proxy rules that block access to localhost, private networks, and cloud metadata ranges as defense in depth.
- Add automated tests covering direct private addresses, IPv6 loopback and private ranges, alternative IP representations, hostname resolution to private addresses, DNS rebinding scenarios, and public-to-private redirects.
- Permit only explicitly required protocols, normally
