T09 · Insecure Skill Coding Practices
- Location
lib/get-agent.js:13- Finding
Unrestricted Fetch of Attacker-Controlled On-Chain Agent URI Enables SSRF
- Content
View full analysis
Vulnerability Details
File Location:
lib/get-agent.js:13-29
Vulnerability Type: Server-Side Request Forgery (SSRF)
Risk Level: HighVulnerable Code
js const [owner, agentURI, wallet] = await Promise.all([ registry.ownerOf(id), registry.tokenURI(id), registry.getAgentWallet(id), ]); const ZERO = "0x0000000000000000000000000000000000000000"; const result = { owner, agentURI, agentWallet: wallet === ZERO ? null : wallet, }; // Try to fetch and parse the agentURI if (agentURI && agentURI.startsWith("http")) { try { const res = await fetch(agentURI); if (res.ok) result.parsedJson = (await res.json()); } catch { // skip — optional } }Technical Analysis
The
agentURIvalue is obtained from an on-chaintokenURIfield that an agent registrant can control.getAgent()automatically performs a server-side request to this value whenever it starts withhttp.The prefix check is not an effective security boundary. It permits both HTTP and HTTPS and does not:
- Reject loopback, private, link-local, multicast, or reserved IP ranges.
- Resolve and validate hostnames against prohibited address ranges.
- Restrict requests to trusted hosts.
- Revalidate destinations after HTTP redirects.
- Enforce connection or response timeouts.
- Limit response size before JSON parsing.
Although the request does not directly transmit the configured
PRIVATE_KEY, it allows an attacker to make the Skill runtime access network resources that are not directly reachable by the attacker. Automatic metadata retrieval is not necessary to return the on-chain owner, wallet, and URI fields, so this behavior exceeds the minimum network privileges needed for the core read operation.Attack Path
- An attacker registers or controls an agent record.
- The attacker sets its on-chain
tokenURIto an internal target, loopback endpoint, cloud metadata endpoint, or attacker-controlled ...[truncated 1113 chars]
- Remediation
View remediation
Remediation Suggestions
- Make remote
agentURIretrieval explicitly opt-in. By default, return the URI without fetching it. - Permit only the
https:protocol unless HTTP support is strictly required. - Resolve the destination hostname and reject all loopback, private, link-local, multicast, unspecified, and reserved IPv4 and IPv6 addresses.
- Disable automatic redirects or validate the protocol, hostname, resolved addresses, and port at every redirect hop.
- Prefer an allowlist of trusted metadata hosts where compatible with the registry design.
- Block sensitive ports and reject URLs containing credentials.
- Apply strict connection and overall request timeouts using an abort signal.
- Stream responses with a conservative maximum byte limit before parsing JSON.
- Validate the response
Content-Typeand parsed document schema. - Consider retrieving metadata through an isolated proxy with restricted egress and no access to internal networks or cloud metadata services.
- Make remote
