T09 · Insecure Skill Coding Practices
- Location
scripts/fetch-markdown.mjs:15- Finding
Bypassable SSRF Protection Allows Access to Internal Network Resources
- Content
View full analysis
= 16 && b <= 31) return true; if (a === 192 && b === 168) return true; return false; } ``` ```js const res = await fetch(u, { signal: ac.signal, redirect: "follow", headers: { "user-agent": "web-markdown-navigator/1.0 (+OpenClaw skill)", accept: "text/html,application/xhtml+xml", }, }); fetchedUrl = res.url || fetchedUrl; const finalUrl = new URL(fetchedUrl); if (isPrivateHost(finalUrl.hostname)) { printErr("ERROR: redirected to private/local host"); process.exit(2); } ``` ### Technical Analysis The URL safety check only blocks selected literal IPv4 addresses and the exact hostnames `localhost`, `127.0.0.1`, `::1`, and `0.0.0.0`. It does not resolve hostnames and validate their A and AAAA records before establishing a connection. Consequently, a public-looking hostname that resolves to a private, loopback, link-local, reserved, or cloud metadata address passes validation. The check also lacks comprehensive IPv6 filtering. IPv6 loopback aliases, unique-local addresses, link-local addresses, IPv4-mapped IPv6 addresses, and other non-public address forms are not rejected. Redirect processing is unsafe because `redirect: "follow"` permits the HTTP client to contact every redirect destination automatically. The final URL is checked only after the redirect chain has already been followed and the destination has been contacted. Although the respo ...[truncated 1990 chars]- Remediation
View remediation
