T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/screenshot.js:21
- Finding
- Unrestricted Browser Access to Internal and Link-Local Network Resources<![CDATA[ ## Vulnerability Details **File Location**: `scripts/screenshot.js`, lines 21–27 and 50–71 **Vulnerability Type**: Server-Side Request Forgery (SSRF)-like unrestricted network access **Risk Level**: Medium ### Vulnerable Code ```js let parsed; try { parsed = new URL(targetUrl); } catch { console.error('Invalid URL:', targetUrl); process.exit(1); } const hostname = parsed.hostname.replace(/\./g, '_'); ``` ```js const pathsToTry = [ parsed.pathname || '/', '/login', '/admin', '/dashboard', '/register', '/signup', '/api', '/debug', '/phpmyadmin', '/wp-admin', '/.env', '/config', '/swagger', '/swagger-ui', '/api-docs', ]; for (const p of pathsToTry) { const url = `${parsed.origin}${p}`; const slug = p.replace(/\//g, '_').replace(/^_/, '') || 'index'; const screenshotPath = path.join(runDir, `${slug}-${timestamp}.png`); const metaPath = path.join(runDir, `${slug}-${timestamp}.json`); try { const response = await page.goto(url, { timeout: 10000, waitUntil: 'domcontentloaded' }); ``` ### Technical Analysis The validation only confirms that the input is syntactically compatible with the Node.js `URL` parser. It does not enforce an allowed protocol or reject loopback, private, link-local, reserved, or otherwise sensitive network destinations. The browser can therefore be directed to resources such as localhost services, RFC 1918 private addresses, or cloud metadata addresses such as `169.254.169.254`. The program also automatically appends sensitive paths including `/.env`, `/config`, `/debug`, `/admin`, and `/api`. Playwright follows HTTP redirects by default. The code does not inspect or revalidate the destination after each redirect, so an initially permitted-looking public address can redirect the browser to an internal service. DNS resolution is also not validated, leaving the implementation potentially exposed to DNS rebinding or hostnames resolving to non-public addresses. Returned pages are c ...[truncated 1748 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Restrict target URLs to the `http:` and `https:` protocols. 2. Require an explicit allowlist of authorized hostnames or target domains. 3. Resolve the hostname before navigation and reject all loopback, private, link-local, multicast, unspecified, and reserved IPv4 and IPv6 ranges. 4. Revalidate the destination after every redirect. Disable automatic redirects where practical and process each redirect only after validating its target. 5. Protect against DNS rebinding by validating every resolved address and ensuring the browser connects only to an approved address. 6. Explicitly reject common metadata destinations, including `169.254.169.254` and relevant IPv6 link-local equivalents. 7. Do not automatically probe sensitive paths. Require each path or path set to be explicitly authorized by the operator. 8. Run Chromium in a network-isolated environment with egress policies that block internal and metadata networks. 9. Apply response-size, navigation-time, and download restrictions to reduce resource-exhaustion and unintended data collection risks. 10. Record the validated final URL and resolved address in the report for auditability. ]]>
