T09 · Insecure Skill Coding Practices
- Location
scripts/verify_agent.py:31- Finding
Unrestricted Agent-Card URL Fetching Enables Server-Side Request Forgery
- Content
View full analysis
dict: """Fetch agent card from URL.""" # Handle well-known URL if not url.endswith(".json") and "/.well-known/" not in url: if not url.endswith("/"): url += "/" url += ".well-known/agent.json" response = requests.get(url, timeout=30) response.raise_for_status() return response.json() ``` ### Technical Analysis The `--url` command-line argument is passed to `requests.get()` without validating its scheme, hostname, resolved IP address, port, or redirect destination. The implementation does not prevent requests to loopback, private, reserved, or link-local addresses. Although fetching an external agent card is part of the declared functionality, unrestricted access to arbitrary network locations exceeds the minimum privileges required. The `requests` library also follows redirects by default, so a publicly accessible URL could redirect the request to an otherwise prohibited internal destination. The 30-second timeout limits request duration but does not mitigate SSRF. There is also no response-size or content-type restriction. ### Attack Path 1. An attacker supplies or induces a user to supply a crafted value through `--url`. 2. The URL references an internal service directly, such as a loopback, private-network, or cloud metadata address, or references an external server that redirects to such an address. 3. `fetch_agent_card()` issues the request from the environment running the Skill. 4. The target service receives a request with the runner's network privileges. 5. If the response is valid JSON, its contents are processed as an agent card. Selected fields or scanner matches may subsequently appear in output, and API mode may send the fetched card to the configured ...[truncated 850 chars]- Remediation
View remediation
