T09 · Insecure Skill Coding Practices
Error
- Location
- assets/main_handler.js:80
- Finding
- Unrestricted URL Retrieval Enables Server-Side Request Forgery## Vulnerability Details **File Location**: `assets/main_handler.js:10-11, 80-83`; also present in `assets/youtube_handler.js:3-4, 32` **Vulnerability Type**: Server-Side Request Forgery through unrestricted browser navigation **Risk Level**: High ### Vulnerable Code ```javascript const targetUrl = process.argv[2]; const videoId = targetUrl?.split('v=')[1]?.split('&')[0]; const mode = targetUrl?.includes('youtube.com') ? 'YOUTUBE' : 'GENERIC'; ``` ```javascript } else { // Generic dynamic page scraping await page.goto(targetUrl, { waitUntil: 'networkidle' }); const title = await page.title(); const content = await page.evaluate(() => document.body.innerText); console.log(JSON.stringify({ status: 'SUCCESS', type: 'GENERIC', title, data: content.substring(0, 10000) })); } ``` The dedicated YouTube handler also navigates directly to an unvalidated argument: ```javascript const targetUrl = process.argv[2]; const videoId = targetUrl.split('v=')[1]?.split('&')[0]; ``` ```javascript await page.goto(targetUrl, { waitUntil: 'networkidle' }); ``` ### Technical Analysis The application accepts a URL directly from the command line and passes it to Playwright without validating its protocol, hostname, port, resolved IP address, or redirect destinations. The generic handler then reads the response body and prints up to 10,000 characters to standard output. Consequently, the browser can be directed to resources reachable from the container but not necessarily reachable by the party supplying the URL. Potential destinations include loopback interfaces, private network ranges, link-local services, internal administration panels, and cloud instance metadata endpoints. Checking whether the input contains `youtube.com` is not a security boundary. Generic URLs receive no destination restrictions, and substring matching does not establish tha ...[truncated 1274 chars]
- Remediation
- ## Remediation Suggestions 1. Parse input with the standard `URL` class and allow only explicitly required schemes, normally `https:` and optionally `http:`. 2. Reject URLs containing credentials, unsupported ports, malformed hostnames, or noncanonical representations. 3. Resolve the destination hostname and reject every address in loopback, private, link-local, multicast, reserved, unspecified, carrier-grade NAT, and cloud metadata ranges for both IPv4 and IPv6. 4. Explicitly block metadata endpoints such as `169.254.169.254` and their IPv6 or provider-specific equivalents. 5. Disable automatic redirects or independently validate every redirect destination before following it. 6. Protect against DNS rebinding by validating the address actually used for the connection, not only an earlier DNS lookup. 7. Prefer a strict hostname allowlist if the skill only needs to support known public services. 8. Apply outbound network controls at the container or host firewall layer so the browser cannot reach private networks or metadata services. 9. Validate YouTube origins using exact parsed hostnames rather than substring matching, and validate the video identifier with the expected format. 10. Add automated tests covering loopback, private IPv4, IPv6 loopback, link-local addresses, alternate numeric IP encodings, redirect chains, and DNS rebinding scenarios.
