T09 · Insecure Skill Coding Practices
- Location
scripts/scrape.py:19- Finding
Insufficient URL Validation Allows Unintended Browser Navigation
- Content
View full analysis
dict: """抓取微信公众号文章""" if not url or "mp.weixin.qq.com" not in url: raise ValueError("请提供有效的微信公众号文章链接(mp.weixin.qq.com)") ``` The URL is then passed directly to Chrome: ```python cmd = [ chrome_path, "--headless=new", "--disable-gpu", "--no-sandbox", f"--user-agent={ua}", "--disable-blink-features=AutomationControlled", "--no-first-run", "--no-default-browser-check", "--virtual-time-budget=20000", "--dump-dom", url ] result = subprocess.run( cmd, capture_output=True, text=True, timeout=40 ) ``` The importer performs no equivalent validation before navigation: ```python def fetch_article_html(url: str, timeout: int = 40) -> str: """用 Chrome headless 抓取文章完整 HTML""" cmd = [CHROME_PATH] + ANTI_DETECT_ARGS + [ f"--virtual-time-budget=20000", "--dump-dom", url ] result = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout) ``` ```python url = args.url.strip() # 自动生成带时间戳的缓存目录 if args.cache_dir: cache_dir = args.cache_dir else: ts = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") cache_dir = f"/tmp/wechat_article_{ts}" os.makedirs(cache_dir, exist_ok=True) # Step 1: 抓取 HTML html = fetch_article_html(url) ``` ### Technical Analysis A substring test does not verify the actual URL scheme or hostname. For example, the following attacker-controlled URL contains the required string but does not navigate to WeChat: ```text https://attacker.example/article?source=mp.weixin.qq.com ``` The import script i ...[truncated 2068 chars]- Remediation
View remediation
str: parsed = urlsplit(value) if parsed.scheme != "https": raise ValueError("Only HTTPS article URLs are allowed") if parsed.hostname != "mp.weixin.qq.com": raise ValueError("Only mp.weixin.qq.com article URLs are allowed") if parsed.username or parsed.password: raise ValueError("URLs containing credentials are not allowed") if parsed.port not in (None, 443): raise ValueError("Unexpected URL port") return value ``` ]]>
