T09 · Insecure Skill Coding Practices
Error
- Location
- content.js:7
- Finding
- Server-Side Request Forgery Through Unrestricted URL Fetching<![CDATA[ ## Vulnerability Details **File Location**: `content.js:7,39-47`; `search.js:70-71,115-122,163-166` **Vulnerability Type**: Server-Side Request Forgery (SSRF) **Risk Level**: High ### Vulnerable Code #### `content.js:7,39-47` ```js const url = process.argv[2]; ``` ```js const response = await fetch(url, { headers: { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.9", }, signal: AbortSignal.timeout(15000), }); ``` #### `search.js:70-71,115-122,163-166` ```js const link = titleLink.getAttribute('href'); if (!link || link.includes('brave.com')) continue; ``` ```js async function fetchPageContent(url) { try { const response = await fetch(url, { headers: { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", }, signal: AbortSignal.timeout(10000), }); ``` ```js if (fetchContent) { for (const result of results) { result.content = await fetchPageContent(result.link); } } ``` ### Technical Analysis `content.js` takes a URL directly from the command line and passes it to `fetch()` without applying a destination security policy. It does not: - Restrict requests to approved URL schemes. - Reject loopback, private, link-local, reserved, multicast, or unspecified IP ranges. - Resolve and validate hostnames before connecting. - Protect against DNS rebinding. - Disable redirects or validate every redirect destination. - Restrict access to cloud instance metadata endpoints. - Enforce a response-size limit before reading the complete response body. Consequently, anyone who can control the argument supplied to `content.js` can make the Agent host initiate requests to network destinations reachable from that host, including s ...[truncated 3366 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Allow only HTTP and HTTPS URLs** - Parse input using the standard `URL` class. - Reject malformed URLs and any scheme other than `http:` or `https:`. - Reject URLs containing unexpected credentials. 2. **Block unsafe network destinations** - Resolve the hostname before connecting. - Reject every resolved IPv4 and IPv6 address in loopback, private, link-local, multicast, reserved, unspecified, and documentation ranges. - Explicitly block known metadata destinations, including link-local metadata addresses. - Apply the policy to every resolved address, not only the first address returned. 3. **Protect against DNS rebinding** - Avoid validating one address and allowing the HTTP client to resolve the hostname independently. - Connect through a security-aware outbound proxy, or pin the validated address while preserving the intended TLS server name and `Host` header. - Prefer a maintained SSRF-protection library or controlled egress gateway over an incomplete custom IP-range implementation. 4. **Validate redirects** - Use `redirect: "manual"` and process redirects explicitly. - Resolve relative `Location` headers safely. - Apply the complete scheme, hostname, DNS, and IP policy to every redirect target. - Set a small maximum redirect count. 5. **Replace substring hostname checks** - Do not use `link.includes('brave.com')` as a trust decision. - Parse the URL and compare normalized hostnames exactly when hostname restrictions are needed. - Treat search-result URLs as untrusted even when they initially point to public hosts. 6. **Constrain downloaded responses** - Require an expected content type before parsing. - Set a maximum response-body size and stop streaming once the limit is exceeded. - Retain strict request timeouts. - Avoid returning raw network error details where they could facilitate internal network discovery. 7. **Apply deployment-level controls** ...[truncated 265 chars]
