T09 · Insecure Skill Coding Practices
- Location
scripts/fetch_wx_article.py:11- Finding
Unrestricted URL Fetching Enables Server-Side Request Forgery
- Content
View full analysis
str: from scrapling.fetchers import Fetcher, FetcherSession page = Fetcher.get(url) ``` ```python def main(): if len(sys.argv) < 2: print("Usage: python3 fetch_wx_article.py ") print("Example: python3 fetch_wx_article.py https://mp.weixin.qq.com/s/xxx") sys.exit(1) url = sys.argv[1] try: content = fetch_wx_article(url) ``` ### Technical Analysis The script accepts a user-controlled command-line argument and passes it directly to `Fetcher.get()` without validating its scheme, hostname, port, resolved IP address, or redirect destination. Although the Skill documentation states that the script is intended for `mp.weixin.qq.com` articles, the implementation does not enforce this restriction. An attacker can therefore submit an arbitrary URL, including URLs targeting: - Loopback services such as `127.0.0.1` or `localhost` - Private network addresses - Link-local services - Cloud instance metadata endpoints - Internal administrative interfaces - Attacker-controlled redirectors that redirect to restricted destinations Simple hostname validation would not be sufficient by itself because DNS rebinding, alternative IP representations, and redirects can bypass incomplete checks. ### Attack Path 1. An attacker provides a non-WeChat URL as the requested article URL. 2. The agent invokes the script with the attacker-controlled value. 3. The value is assigned directly from `sys.argv[1]` to `url`. 4. `fetch_wx_article()` passes the URL to `Fetcher.get()` without validation. 5. The request executes from the environment where the Skill is running. 6. If the destination is reachable, its response is converted to Markdown and printed to standard output ...[truncated 768 chars]- Remediation
View remediation
