T05 · Unauthorized Access and Privilege Escalation
- Location
handler.py:5- Finding
Unrestricted Server-Side Request Forgery Through User-Controlled URLs
- Content
View full analysis
dict: try: resp = requests.get(url, timeout=10) ``` ```python def handle(input_text: str, user_id: str = "default") -> dict: url = re.search(r'https?://[^\s]+', input_text) if not url: return {"error": "Please provide a URL"} return analyze_seo(url.group(0)) ``` ### Technical Analysis The handler extracts an arbitrary HTTP or HTTPS URL from attacker-controlled input and passes it directly to `requests.get()`. It does not validate the destination hostname, resolved IP address, network range, port, or redirect chain. The timeout only limits request duration; it does not prevent access to loopback addresses, private networks, link-local services, cloud metadata endpoints, or other resources reachable from the execution environment. Because redirects are followed by `requests` by default, checking only the initial URL would also be insufficient. The implementation reads the full response body through `resp.text` without imposing a maximum response size. This creates an additional resource-exhaustion risk when a remote server returns an excessively large response. ### Attack Path 1. An attacker submits an SEO request containing a URL that targets an internal or privileged endpoint, such as a loopback address, RFC 1918 address, or link-local cloud metadata service. 2. `handle()` accepts the URL because it only verifies that the string begins with `http://` or `https://`. 3. `analyze_seo()` causes the Skill host to issue the request from its own network context. 4. The target response is loaded into memory and parsed. 5. Extracted title, description, and heading data—or network and application details contained in returned errors—may be exposed to the attacker. 6. The attacker can repeat the process against different hosts ...[truncated 1063 chars]- Remediation
View remediation
