T09 · Insecure Skill Coding Practices
- Location
scripts/wechat_to_md.py:62- Finding
Arbitrary URL Fetching Enables Server-Side Request Forgery
- Content
View full analysis
str: raw = raw.strip() raw = html_unescape(raw) if raw.startswith("//"): raw = "https:" + raw if not raw.startswith("http"): raw = "https://" + raw return raw ``` The normalized URL is passed directly to Playwright: ```python page.goto(url, wait_until="domcontentloaded", timeout=timeout) ``` The fallback request implementation also accepts the URL directly and follows redirects: ```python resp = session.get(url, timeout=20, allow_redirects=True) ``` Both public conversion functions invoke the unrestricted fetch operation: ```python url = normalize_url(url) print(f"[*] 正在抓取: {url}") html = fetch_html(url, use_playwright=use_playwright) ``` ```python url = normalize_url(url) html = fetch_html(url, use_playwright=use_playwright) ``` ### Technical Analysis `normalize_url()` only performs syntactic normalization. It does not verify: - That the URL uses an approved scheme. - That the hostname is exactly `mp.weixin.qq.com`. - That the resolved address is not loopback, private, link-local, reserved, or otherwise internal. - That redirect destinations remain within the permitted domain. - That the URL does not contain embedded credentials or hostname-confusion syntax. This conflicts with the documented claim that the Skill only supports `mp.weixin.qq.com` articles. Both Playwright and `requests` can therefore be directed to arbitrary network locations. The `requests` path explicitly follows redirects, while browser navigation normally follows HTTP redirects as well. The parser also accepts the generic `article` selector as a content containe ...[truncated 1733 chars]- Remediation
View remediation
