T09 · Insecure Skill Coding Practices
- Location
src/converter.js:219- Finding
Arbitrary Blog URL Fetching Enables Server-Side Request Forgery
- Content
View full analysis
Vulnerability Details
File Location:
src/converter.js:219-225; reachable frombin/cli.js:68-72andbin/cli.js:109-113
Vulnerability Type: Server-Side Request Forgery (SSRF)
Risk Level: HighVulnerable Code
javascript async fetchBlogContent(url) { try { const response = await axios.get(url, { headers: { 'User-Agent': 'Mozilla/5.0' }, timeout: 10000 });The affected CLI commands pass user-controlled URLs directly to this method:
javascript if (source.startsWith('http')) { console.log('📥 Fetching blog content...'); content = await converter.fetchBlogContent(source); }Technical Analysis
The
blog-to-twitterandblog-to-linkedincommands accept a user-controlled source. Any value beginning withhttpis submitted toaxios.get()without validating its scheme, hostname, port, resolved IP address, or redirect destination.A timeout limits request duration but does not restrict where the request can be sent. Consequently, the process can be induced to contact:
- Loopback services such as
127.0.0.1or::1 - Private-network services
- Link-local addresses and cloud instance metadata services
- Internal administrative interfaces that are unavailable to the external attacker
- Public URLs that redirect to one of these prohibited destinations
After retrieval, the response is parsed as page content. For normal conversion operations, up to 8,000 characters of the extracted content are placed in an AI prompt and sent to the configured OpenAI API. Therefore, data obtained through SSRF may be incorporated into generated output or transmitted to the declared external AI provider.
Remote URL retrieval is necessary for the documented blog-import feature, but unrestricted access to arbitrary network destinations exceeds the minimum network privileges needed to fetch public blog posts.
Attack Path
- An attacker supplies or persu ...[truncated 1255 chars]
- Loopback services such as
- Remediation
View remediation
Remediation Suggestions
- Parse input with
new URL()and reject malformed URLs. - Permit only explicitly required schemes, preferably HTTPS.
- Reject embedded credentials, nonstandard ports, and hostnames not required by the feature.
- Resolve the destination hostname before connecting and block loopback, private, link-local, multicast, unspecified, and reserved IPv4 and IPv6 ranges.
- Repeat destination validation after every DNS resolution and for every redirect target.
- Disable automatic redirects or implement a bounded redirect handler that validates each destination before following it.
- Consider an explicit public-domain allowlist or a controlled outbound proxy.
- Apply response-size limits in addition to the existing timeout.
- Clearly notify users that fetched article content will be submitted to OpenAI when AI processing is enabled.
- Add tests covering loopback addresses, private ranges, IPv6, alternative numeric IP representations, DNS rebinding scenarios, and redirects to blocked destinations.
- Parse input with
