T09 · Insecure Skill Coding Practices
- Location
runtime.py:273- Finding
Unvalidated Seed URLs Allow Server-Side Request Forgery and Excessive Browser Access
- Content
View full analysis
= request["max_articles"]: break try: probe = fetch_page(url, timeout=20) access_meta = classify_page( source_url=url, html_text=probe["html"], final_url=probe["final_url"], ) ``` It may also be passed to a persistent Playwright browser context: ```python browser_engagement: dict[str, Any] | None = None public_engagement = extraction["data"].get("engagement") or {} if request["collect_engagement"] and not public_engagement.get("metrics_visible_in_public_html"): try: browser_engagement = run_node_script( engagement_script, str(workspace_root), url, str(browser_profile_dir), cwd=workspace_root, ) ``` ```javascript const [, , workspaceRoot, sourceUrl, profileDir] = process.argv; if (!workspaceRoot || !sourceUrl || !profileDir) { throw new Error('Usage: node collect_engagement.js '); } const playwright = resolvePlaywright(workspaceRoot); if (!playwright) { throw new Error('Playwright dependency not found. Install playwright or reuse ...[truncated 3427 chars]- Remediation
View remediation
str: normalized = canonicalize_url(value) parsed = urllib.parse.urlparse(normalized) if parsed.scheme != "https": raise ValueError("Only HTTPS WeChat article URLs are permitted.") if parsed.hostname != "mp.weixin.qq.com": raise ValueError("Only mp.weixin.qq.com URLs are permitted.") if parsed.port not in {None, 443}: raise ValueError("Nonstandard ports are not permitted.") if not parsed.path.startswith("/s"): raise ValueError("The URL is not a supported WeChat article URL.") if parsed.username or parsed.password: raise ValueError("URLs containing credentials are not permitted.") return normalized ``` 2. Apply validation to every `seed_urls` entry before it is added to `candidate_urls`. 3. Resolve destination hostnames and reject loopback, private, link-local, multicast, reserved, and unspecified IPv4 and IPv6 addresses. 4. Disable automatic redirects or validate every redirect destination before following it. 5. Repeat validation immediately before each HTTP request and browser navigation to reduce time-of-check/time-of-use and DNS rebinding risks. 6. Pass the validated canonical URL—not the original untrusted URL—to the extraction and engagement helpers. 7. Use a new temporary browser profile for public collection. Only reuse an authenticated persistent profile after explicit user consent. 8. Isolate browser execution with restricted filesystem access, no unnecessary extensions, and egress limited to required WeChat domains. 9. Add tests covering loopback addresses, private IP ranges, IPv6 literals, encoded hostnames, user-info syntax, nonstandard ports, redirects, and DNS rebinding cases. 10. Avoid writing response excerpts from restricted or unexpected destinations into reports. ]]>
