T09 · Insecure Skill Coding Practices
- Location
scripts/api-translator.py:10- Finding
Unrestricted URL Fetching Enables Server-Side Request Forgery
- Content
View full analysis
Vulnerability Details
File Location:
scripts/api-translator.py:10-16, 20-29;scripts/api-translator.sh:4-16;SKILL.md:21-23
Vulnerability Type: Server-Side Request Forgery through an unvalidated user-supplied URL
Risk Level: MediumVulnerable Code
scripts/api-translator.py:10-16:python def fetch_url(url: str) -> str: """抓取網頁內容""" result = subprocess.run( ["web_fetch", "--url", url, "--maxChars", "50000"], capture_output=True, text=True ) return result.stdoutscripts/api-translator.py:20-29:python def main(): if len(sys.argv) < 2: print("用法: api-translator <API文檔URL>") print("範例: api-translator https://api.example.com/docs") sys.exit(1) url = sys.argv[1] print(f"🌐 抓取 API 文檔: {url}") # 抓取內容 content = fetch_url(url)scripts/api-translator.sh:4-16:bash URL="$1" if [ -z "$URL" ]; then echo "用法: api-translator <URL>" echo "範例: api-translator https://api.example.com/docs" exit 1 fi echo "正在抓取 API 文檔: $URL" echo "..." # 抓取網頁內容 CONTENT=$(web_fetch --url "$URL" --maxChars 50000 2>/dev/null)SKILL.md:21-23:markdown 1. 使用 `web_fetch` 工具抓取 API 文檔內容 2. 將內容發送給 LLM 翻譯 3. 輸出翻譯結果Technical Analysis
Both executable implementations accept a URL directly from the command line and pass it unchanged to
web_fetch. They do not validate the URL scheme, hostname, port, resolved IP address, or redirect destination.Although the use of an argument array in the Python implementation and quoting in the shell implementation prevent ordinary shell-command injection through the URL, they do not prevent network-target injection. If
web_fetchhas access to the host's loopback interface, private networks, link-local services, or cloud metadata endpoints, an attacker can use this behavior a ...[truncated 2667 chars]- Remediation
View remediation
Remediation Suggestions
Implement centralized URL validation before every fetch:
- Parse the URL with a standards-compliant URL parser and reject malformed URLs.
- Allow only the
httpsscheme unless plain HTTP is explicitly required. - Reject URLs containing embedded credentials or unsupported ports.
- Resolve the hostname and reject every resolved address belonging to loopback, private, link-local, multicast, unspecified, reserved, or other non-public ranges for both IPv4 and IPv6.
- Apply the same validation to every redirect destination before following it.
- Protect against DNS rebinding by ensuring that the validated destination is the address used for the connection, or by enforcing equivalent restrictions through a trusted outbound proxy.
- Prefer an explicit allowlist of approved API-documentation domains where the deployment permits it.
- Enforce network-layer egress controls so the process cannot reach cloud metadata endpoints, localhost, or private network ranges even if application validation is bypassed.
- Set conservative connection and response timeouts, response-size limits, and redirect limits.
- Avoid printing fetched content that may contain sensitive data. Return a controlled error when a prohibited destination is supplied.
- Treat all fetched documents as untrusted data before placing them into an LLM context, and explicitly instruct the agent not to follow instructions embedded in fetched documentation.
- Add tests covering direct private addresses, IPv6 loopback, alternate IP representations, DNS names resolving to private addresses, user-information syntax, nonstandard ports, and public-to-private redirects.
