T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/extract-styles.py:159
- Finding
- Unrestricted URL Navigation Enables Server-Side Request Forgery<![CDATA[ ## Vulnerability Details **File Location**: - `scripts/extract-styles.py:159-166` - `scripts/extract-keyframes.py:5-11` **Vulnerability Type**: Server-Side Request Forgery through unrestricted browser navigation **Risk Level**: High ### Vulnerable Code `scripts/extract-styles.py:159-166`: ```python def extract(url: str, switch_dark: bool = False, out_path: str = None): with sync_playwright() as p: browser = p.chromium.launch(headless=True) page = browser.new_page(viewport={"width": 1280, "height": 800}) print(f"[extract-styles] Navigating to {url}", file=sys.stderr) page.goto(url, wait_until="networkidle", timeout=30000) ``` `scripts/extract-keyframes.py:5-11`: ```python def extract_keyframes(url, output_file): with sync_playwright() as p: browser = p.chromium.launch() page = browser.new_page() page.goto(url, wait_until="networkidle", timeout=30000) ``` ### Technical Analysis Both scripts pass a caller-controlled URL directly to Playwright's `page.goto()` without validating the URL scheme, destination hostname, resolved IP address, or redirect chain. There are no controls preventing navigation to: - Loopback destinations such as `127.0.0.1` or `localhost` - Private network ranges - Link-local or cloud metadata addresses - Internal DNS names - Non-HTTP schemes such as `file:` or `data:` - Public URLs that redirect to otherwise prohibited destinations The browser subsequently evaluates JavaScript against the loaded document and extracts its title, final URL, CSS variables, computed colors, typography, background resources, and other document metadata. This turns the scripts into a limited request-and-observation proxy operating from the agent's network environment. ### Attack Path 1. An attacker or untrusted user supplies an internal destination as the extraction URL. 2. The skill forwards the value unchanged to `page.goto()`. 3. Chromium requests the destination using the netwo ...[truncated 1146 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Accept only explicitly supported schemes, preferably `https` and optionally `http`. 2. Reject URLs containing embedded credentials or unsupported schemes such as `file:`, `data:`, `javascript:`, and `ftp:`. 3. Resolve the destination hostname before navigation and reject addresses in loopback, private, link-local, multicast, unspecified, and reserved ranges for both IPv4 and IPv6. 4. Intercept browser requests through Playwright routing and repeat destination validation for every subrequest. 5. Validate every redirect target rather than only the original URL. 6. Consider requiring an explicit hostname allowlist when the skill is used in sensitive environments. 7. Run Chromium in an isolated container with restricted egress and no access to internal networks or cloud metadata endpoints. 8. Add automated tests covering encoded IP addresses, IPv6, DNS rebinding, alternate numeric address formats, and public-to-private redirects. ]]>
