T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/run_axe_playwright.js:66
- Finding
- Unrestricted URL Navigation Enables Server-Side Request Forgery<![CDATA[ ## Vulnerability Details **File Location**: `scripts/run_axe_playwright.js:66-83`, with the resulting navigation at `scripts/run_axe_playwright.js:288` **Vulnerability Type**: Server-Side Request Forgery through unrestricted browser navigation **Risk Level**: Medium ### Vulnerable Code ```js function normalizeUrl(raw) { if (!raw) { return null; } const value = String(raw).trim(); if (!value) { return null; } try { const url = new URL(value); if (url.protocol !== "http:" && url.protocol !== "https:") { return null; } return url.toString(); } catch (_error) { return null; } } ``` The accepted URL is subsequently opened by headless Chromium: ```js await page.goto(url, { waitUntil: "domcontentloaded", timeout: timeoutMs }); ``` ### Technical Analysis The URL validation only restricts the protocol to HTTP or HTTPS. It does not reject: - IPv4 or IPv6 loopback addresses - RFC 1918 private-network addresses - Link-local addresses - Cloud instance metadata endpoints - Internal DNS hostnames - Public URLs that redirect to private or link-local destinations - URLs containing embedded credentials or sensitive query parameters Because `page.goto()` performs the request from the environment running the audit, an attacker who controls an audit URL or URL-list entry can cause that environment to access services that may not be reachable from the attacker's own network. Axe subsequently examines the loaded page. Selected DOM evidence, including violation-related HTML, selectors, page URLs, and errors, can be written to `outputs/axe-results.json` and `outputs/axe-summary.md`. The reviewed code does not transmit these files to an external party, so extraction would require access to generated outputs or another disclosure mechanism. ### Attack Path 1. An attacker supplies or influences a URL passed through `--url` or `--urls-file`. 2. The attacker uses a destination such as a loopback service, private-network ...[truncated 1562 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Resolve destination hostnames before navigation and reject all resolved addresses in prohibited ranges, including: - IPv4 and IPv6 loopback - RFC 1918 private networks - IPv4 and IPv6 link-local ranges - Unique-local IPv6 ranges - Multicast, reserved, and unspecified addresses - Known cloud metadata addresses 2. Revalidate every redirect destination. Initial URL validation alone is insufficient because a public endpoint can redirect to an internal address. 3. Use a default-deny hostname allowlist where possible. If internal accessibility auditing is required, enable it only through an explicit option and document the associated trust requirements. 4. Run Chromium in a network-isolated environment with egress rules that prevent access to internal control planes and metadata services. 5. Reject URLs containing username/password components and redact sensitive query strings before logging or persisting them. 6. Limit response size, redirect count, and total navigation time to reduce denial-of-service exposure. 7. Add automated tests covering loopback, private IPv4, private IPv6, link-local, alternative IP representations, internal DNS resolution, DNS rebinding, and redirects to prohibited destinations. ]]>
