T09 · Insecure Skill Coding Practices
- Location
scripts/web_intel.py:113- Finding
Unrestricted URL Fetching Through the User's Authenticated Browser Session
- Content
View full analysis
Vulnerability Details
File Location:
scripts/web_intel.py:113-140, 225-229, 280-284
Vulnerability Type: Server-Side Request Forgery and authenticated-browser data exposure
Risk Level: HighVulnerable Code
python def _cdp_fetch(url: str, timeout: int = 15) -> str | None: """Extract page content through the web-access CDP Proxy.""" target_id = None try: # Create a background tab new_resp = urllib.request.urlopen( f"{CDP_PROXY_URL}/new?url={urllib.parse.quote(url, safe=':/?=#&')}", timeout=timeout, ) data = json.loads(new_resp.read()) target_id = data.get("targetId") or data.get("id") if not target_id: return None # Extract page body through JavaScript evaluation eval_req = urllib.request.Request( f"{CDP_PROXY_URL}/eval?target={target_id}", data=b"document.body ? document.body.innerText : ''", method="POST", ) content = urllib.request.urlopen(eval_req, timeout=timeout).read().decode( "utf-8", errors="replace" ) return content[:12000] if content else Nonepython else: # deep: prefer CDP, then use fallback services if cdp: full_content = _cdp_fetch(url) tool = "web_access_cdp"python p.add_argument("--url", help="Directly extract the specified URL and skip search")Technical Analysis
The
--urlargument is passed into_cdp_fetch()without validating its scheme, hostname, resolved IP address, port, or redirect destination. When deep mode is selected and the local CDP proxy is available, the URL is opened in the user's Chrome environment. The Skill documentation states that this browser environment carries the user's authenticated session.URL encoding does not establish a security boundary. The implementation does not rest ...[truncated 2412 chars]
- Remediation
View remediation
Remediation Suggestions
- Parse targets with a strict URL parser and permit only explicitly required schemes, normally
httpsand optionallyhttp. - Reject URLs containing user-information components, malformed hosts, ambiguous numeric IP representations, or unsupported ports.
- Resolve the hostname before navigation and reject every address in loopback, private, link-local, multicast, reserved, unspecified, and other non-public ranges for both IPv4 and IPv6.
- Explicitly block known metadata destinations, including link-local metadata addresses and provider-specific metadata hostnames.
- Disable automatic redirects or validate every redirect target using the same scheme, hostname, DNS, and IP-address checks before following it.
- Protect against DNS rebinding by binding validation to the address actually used for the connection rather than trusting a single preliminary DNS lookup.
- Prefer an approved-domain allowlist for authenticated CDP extraction.
- Require explicit, informed user confirmation before opening a target through a browser context that carries authentication state.
- Use an isolated, unprivileged browser profile without personal cookies for general-purpose extraction. Reserve authenticated profiles for narrowly scoped, user-approved domains.
- Apply authorization and origin checks to the local CDP proxy and ensure it is not accessible to untrusted local or remote processes.
- Avoid returning authenticated page content by default. Redact sensitive values, minimize output, and clearly identify when content came from an authenticated session.
- Add automated tests covering loopback addresses, private IPv4 and IPv6 ranges, metadata endpoints, encoded IP forms, alternate ports, redirects to internal destinations, and DNS-rebinding scenarios.
- Parse targets with a strict URL parser and permit only explicitly required schemes, normally
