T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/domain-screenshot.js:27- Finding
Browser-Based Server-Side Request Forgery Through Unrestricted Domain Navigation
- Content
View full analysis
Vulnerability Details
File Location:
scripts/domain-screenshot.js:27-31, 69-76
Vulnerability Type: Server-Side Request Forgery (SSRF)
Risk Level: HighVulnerable Code
js const domain = process.argv[2] || 'example.com'; // Security: Validate domain - only allow alphanumeric, hyphen, dot const safeDomain = domain.replace(/[^a-zA-Z0-9.-]/g, ''); if (safeDomain !== domain) { fail('Screenshot failed: Invalid characters in domain'); }js // Try https first, then http const urls = ['https://' + safeDomain, 'http://' + safeDomain]; let navigated = false; for (const url of urls) { try { await page.goto(url, { waitUntil: 'load', timeout: 30000 }); navigated = true; break; } catch (_) { // try next } }Technical Analysis
The validation only restricts the characters used in the destination. It does not establish that the supplied destination is a public Internet domain. Inputs such as
localhost,127.0.0.1, private IPv4 addresses, IPv6-derived hostnames, and attacker-controlled domains resolving to internal addresses can pass this check.Playwright navigation also follows HTTP redirects by default. Consequently, an initially public hostname can redirect the browser to a loopback, private, link-local, or otherwise restricted endpoint. The script does not validate DNS resolution results or redirect destinations before allowing Chromium to connect.
The Skill instructions state that a successful screenshot is subsequently sent through the messaging tool. Therefore, content rendered from an internal service may be captured and returned to the requester. This network access exceeds the least privilege required to inspect public domains.
Attack Path
- An attacker asks the Skill to inspect a syntactically valid internal destination, such as
127.0.0.1, or an attacker-controlled public hostname. - The input passes the character-based v ...[truncated 1190 chars]
- An attacker asks the Skill to inspect a syntactically valid internal destination, such as
- Remediation
View remediation
Remediation Suggestions
- Require a registrable public hostname rather than accepting arbitrary host-like strings or IP literals.
- Resolve the hostname before navigation and reject every result in loopback, private, link-local, multicast, unspecified, documentation, reserved, and other non-public IPv4 and IPv6 ranges.
- Re-resolve and validate the destination immediately before connection to reduce DNS-rebinding exposure.
- Disable redirects where possible. If redirects are required, inspect and validate every redirect destination before navigation continues.
- Use Playwright request interception to block requests to non-public addresses, including subresources initiated by the loaded page.
- Consider running Chromium in an isolated network namespace that can access only public HTTP and HTTPS destinations.
- Apply the same public-address policy to all WHOIS, DNS, TLS, and browser-related stages rather than relying solely on character validation.
- Add tests covering loopback addresses, RFC 1918 addresses, link-local addresses, IPv6 private ranges, DNS rebinding, and public-to-private redirects.
