T09 · Insecure Skill Coding Practices
- Location
scripts/scraper.py:45- Finding
Unrestricted URL Navigation Enables Server-Side Request Forgery and Local Resource Access
- Content
View full analysis
Vulnerability Details
File Location:
scripts/scraper.py:45-48,scripts/scraper.py:139-151, andscripts/browser.py:58-61
Vulnerability Type: Server-Side Request Forgery (SSRF) and unsafe URL scheme handling
Risk Level: MediumVulnerable Code
scripts/scraper.py:45-48:python if html is None: try: response = requests.get(url, timeout=10) html = response.textscripts/scraper.py:139-151:python if use_browser: logger.info("Using browser (SPA detected)") html = get_html(url) else: logger.info("Using requests (static site)") try: response = requests.get(url, timeout=30) response.raise_for_status() html = response.text except requests.RequestException as e: logger.error(f"Failed to fetch {url}: {e}") if detect_spa(url): logger.info("Retrying with browser...") html = get_html(url)scripts/browser.py:58-61:python try: logger.info(f"Navigating to: {url}") self._page.goto(url, timeout=timeout, wait_until="networkidle") return TrueTechnical Analysis
The user-controlled
--urlargument is passed directly torequests.get()and Playwright'spage.goto()without validation of:- The URL scheme
- The hostname
- The resolved IP address
- Redirect destinations
- Loopback, private, link-local, reserved, or cloud metadata address ranges
The
requestspath can therefore issue HTTP or HTTPS requests to services reachable from the machine running the skill, including internal network services and cloud instance metadata endpoints. Because redirects are followed by default, a public URL may also redirect to a prohibited internal destination.The forced SPA/browser path provides a broader attack surface because Playwright can navigate schemes other than HTTP and HTTPS. In particular, a supplied
file://URL may allow the browser to load a locally accessible HTML document. If that document contains a ...[truncated 1573 chars]- Remediation
View remediation
Remediation Suggestions
- Parse every supplied URL using a standards-compliant URL parser and allow only
httpandhttpsschemes. Explicitly rejectfile,data,javascript, and other schemes. - Require a non-empty hostname and reject embedded credentials, malformed ports, and ambiguous host representations.
- Resolve the hostname before making a request and reject every resolved address that is loopback, private, link-local, multicast, reserved, or unspecified.
- Explicitly block cloud metadata destinations, including link-local metadata addresses and provider-specific metadata hostnames.
- Disable automatic redirects or validate every redirect destination using the same scheme, hostname, DNS, and IP-address controls before following it.
- Revalidate the actual connection destination to mitigate DNS rebinding and time-of-check/time-of-use discrepancies.
- Apply identical URL controls to both the
requestsand Playwright paths. - Where operationally possible, use an explicit domain allowlist and execute the browser in a network sandbox that cannot reach internal networks or metadata services.
- Add automated tests covering loopback addresses, IPv6 loopback, private ranges, link-local addresses, alternative numeric IP representations, redirect-based bypasses, DNS rebinding scenarios, and prohibited schemes.
- Parse every supplied URL using a standards-compliant URL parser and allow only
