← Back to PRs

#8305: fix(browser): add SSRF protection to browser navigation

by yubrew open 2026-02-03 21:30 View on GitHub →
stale
## Summary Add SSRF (Server-Side Request Forgery) protection to browser navigation to prevent malicious URL access via the browser automation API. ## The Problem The `navigateViaPlaywright()` function accepts arbitrary URLs and passes them directly to Playwright's `page.goto()` without validation. This allows an attacker to direct the browser to: - Local files via `file:///etc/passwd` - Cloud metadata endpoints via `http://169.254.169.254/latest/meta-data/` - Internal network services via `http://192.168.1.1/admin` - Localhost services via `http://localhost:8080/` This is a form of SSRF where the browser acts as a proxy to access internal resources. See [CWE-918: Server-Side Request Forgery](https://cwe.mitre.org/data/definitions/918.html). ## Changes - `src/browser/pw-tools-core.snapshot.ts`: Add URL validation before `page.goto()` using existing SSRF utilities - `src/browser/pw-tools-core.ssrf-navigation.test.ts`: Add comprehensive tests for SSRF protection The fix validates URLs before navigation by: 1. Parsing the URL (rejects malformed URLs) 2. Blocking non-http(s) protocols (file://, javascript:, data:, etc.) 3. Blocking internal hostnames (localhost, .local, .internal, metadata.google.internal) 4. Blocking private IP literals (127.0.0.1, 10.x.x.x, 192.168.x.x, 172.16-31.x.x, 169.254.x.x, IPv6 equivalents) ## Test Plan - [x] `pnpm build && pnpm check && pnpm test` passes - [x] New test `describe('VULN-013: browser navigation SSRF protection')` validates the fix with 16 test cases - [x] Tests cover protocol blocking, hostname blocking, private IP blocking, and valid URL passthrough ## Related - [CWE-918](https://cwe.mitre.org/data/definitions/918.html) - Server-Side Request Forgery - Internal audit ref: VULN-013 --- *Built with [bitsec-ai](https://github.com/bitsec-ai). AI-assisted: Yes. Testing: fully tested (test written before fix). Code reviewed and understood.* <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR adds SSRF defenses to `navigateViaPlaywright()` by parsing and validating the navigation URL before calling Playwright’s `page.goto()`. It blocks non-HTTP(S) schemes, known internal hostnames (e.g. `localhost`, `.local`, `.internal`, `metadata.google.internal`), and private IP literals (IPv4 and IPv6). A new Vitest suite exercises protocol blocking, hostname blocking, private IP blocking, and allows known-good public URLs. The change fits into the existing infra SSRF utilities (`src/infra/net/ssrf.ts`) by reusing the hostname/IP predicate helpers, but currently only applies the “literal” checks at navigation time. <h3>Confidence Score: 3/5</h3> - This PR improves safety but may still be bypassable via hostnames that resolve to private/internal IPs. - The added URL parsing and literal protocol/hostname/IP checks are straightforward and well-tested, but the implementation does not appear to validate DNS resolution (so DNS rebinding / internal-resolution SSRF can still succeed). That remaining gap is significant for an SSRF fix, though it doesn’t introduce obvious regressions. - src/browser/pw-tools-core.snapshot.ts (navigation SSRF policy enforcement) <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs