T09 · Insecure Skill Coding Practices
- Location
src/converter.js:219- Finding
Unrestricted URL Fetching Enables Server-Side Request Forgery
- Content
View full analysis
Vulnerability Details
File Location:
bin/cli.js:69-71,bin/cli.js:110-112, andsrc/converter.js:219-225
Vulnerability Type: Server-Side Request Forgery
Risk Level: HighThe blog conversion commands accept an arbitrary value beginning with
httpand pass it directly to an unrestricted Axios request.javascript // bin/cli.js:69-71 if (source.startsWith('http')) { console.log('📥 Fetching blog content...'); content = await converter.fetchBlogContent(source); }The same behavior is present in the LinkedIn conversion command:
javascript // bin/cli.js:110-112 if (source.startsWith('http')) { console.log('📥 Fetching blog content...'); content = await converter.fetchBlogContent(source); }The destination is fetched without validating its host, resolved IP address, port, or redirect chain:
javascript // src/converter.js:219-225 async fetchBlogContent(url) { try { const response = await axios.get(url, { headers: { 'User-Agent': 'Mozilla/5.0' }, timeout: 10000 });Technical Analysis
Checking only whether a value starts with
httpis not a security boundary. The code does not parse the URL using a strict URL parser or limit requests to public blog hosts. Consequently, callers can request loopback, private-network, link-local, or cloud metadata destinations.Axios also follows redirects by default. An initially public URL can therefore redirect to an internal destination unless every redirect target is independently validated. The timeout limits request duration but does not prevent access to sensitive network locations. No response-size limit is configured either, allowing a hostile endpoint to return an excessively large body.
The fetched response is parsed as article content and then supplied to the OpenAI transformation method. This can cause information obtained from an internal service to leave the local environment ...[truncated 1510 chars]
- Remediation
View remediation
Remediation Suggestions
- Parse destinations with the standard
URLclass and permit only explicithttp:andhttps:protocols. - Reject URLs containing credentials, ambiguous host representations, or unsupported ports.
- Resolve the hostname before connecting and reject loopback, private, link-local, multicast, reserved, and cloud metadata address ranges for both IPv4 and IPv6.
- Disable automatic redirects or validate the scheme, hostname, resolved address, and port of every redirect target.
- Prefer an explicit allowlist of trusted blog domains when the deployment permits it.
- Set conservative
maxContentLengthandmaxBodyLengthlimits. - Restrict response content types to expected textual or HTML formats.
- Run network fetching in a sandbox with no access to internal services or metadata endpoints.
- Require explicit user confirmation before transferring fetched content to OpenAI.
- Add tests covering loopback addresses, private IP addresses, IPv6 literals, alternative numeric IP representations, DNS rebinding, and redirect-based bypasses.
- Parse destinations with the standard
