T09 · Insecure Skill Coding Practices
- Location
yumnb/cli.py:323- Finding
Unrestricted URL Fetching Enables Server-Side Request Forgery
- Content
View full analysis
dict: import requests html, title = "", "" try: r = requests.get(url, timeout=20, headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"}) if r.status_code == 200: html = r.text except Exception as e: html = f"" if (not html or "" not in html.lower()) and fetcher: try: out = subprocess.run(fetcher.split() + [url], capture_output=True, text=True, encoding="utf-8", timeout=60) if out.returncode == 0 and out.stdout: html = out.stdout except Exception as e: print(f"fetcher fallback failed: {e}") ``` ### Technical Analysis The `ingest_url` function performs an HTTP request to a user-supplied URL without validating its destination. It does not reject loopback, private, link-local, reserved, or cloud metadata addresses. The `requests` library also follows redirects by default, and redirected destinations are not revalidated. Consequently, an untrusted user who can control the ingestion input can use the Skill's network position to request resources that are not directly reachable from the attacker's system. Relevant targets include: - Loopback services such as `127.0.0.1` - Private network services in RFC 1918 address ranges - Link-local services and cloud metadata endpoints - Internal administration interfaces - Public hosts that redirect to private destinations - Hostnames affected by DNS rebinding A successful HTTP response is written into the generated notebook's `source/page.html` and extracted into `source/raw.txt`. If automatic summarization is enabled, up to 60,000 characters of the retrieved source are subsequently provid ...[truncated 1793 chars]- Remediation
View remediation
