T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/fusion_search.py:157
- Finding
- Unrestricted Server-Side Navigation Enables SSRF<![CDATA[ ## Vulnerability Details **File Location**: `scripts/fusion_search.py:157-184`, with the vulnerable function invoked at `scripts/fusion_search.py:302-307` **Vulnerability Type**: Server-Side Request Forgery through unrestricted browser navigation **Risk Level**: High ### Vulnerable Code ```python def fetch_full_content(page, url, timeout=8000): """全文抓取""" try: page.goto(url, wait_until="domcontentloaded", timeout=timeout) time.sleep(1.5) try: page.wait_for_load_state("networkidle", timeout=5000) except Exception: pass # 删除干扰元素 page.evaluate("""() => { for (const s of document.querySelectorAll( 'script, style, nav, header, footer, .ad, .sidebar, ' + '.comment, .popup, .modal, .cookie, .advertisement, ' + 'noscript, iframe, .related, .recommend, .share' )) s.remove(); }""") # 优先找主要内容区域 content = page.evaluate("""() => { const main = document.querySelector('article, main, .content, ' + '.post, .article, #content, #main, .entry-content, ' + '.post-content, [role="main"]'); if (main) return main.innerText; return document.body ? document.body.innerText : ''; }""") content = re.sub(r'\s+', ' ', content).strip() return content[:8000] except Exception: return "" ``` The URL is taken directly from search results: ```python for i, r in enumerate(results[:count]): content = fetch_full_content(page, r["url"], timeout=10000) if content: results[i]["content"] = content ``` ### Technical Analysis The full-content extraction feature navigates to search-result URLs without validating: - The URL scheme - The destination hostname - The resolved IP address - Redirect destinations - Loopback, private, link-local, or reserved address ranges - Cloud metadata endpoints - DNS ...[truncated 2264 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Permit only explicitly supported schemes, normally `https` and, if necessary, `http`. 2. Resolve the destination hostname before navigation and reject every address in: - Loopback ranges - RFC1918 private ranges - Link-local ranges - Carrier-grade NAT ranges - Multicast and reserved ranges - IPv6 loopback, unique-local, and link-local ranges - Known cloud metadata addresses 3. Validate every redirect destination rather than only the original result URL. 4. Pin the validated IP for the connection or use a controlled outbound proxy to prevent DNS rebinding. 5. Apply an outbound network policy that prevents the browser container from reaching internal networks and metadata endpoints. 6. Consider restricting full-content extraction to an explicit user request instead of enabling it automatically through routing rules. 7. Use a strict destination allowlist where operationally possible. 8. Return an explicit validation error rather than silently navigating to an unsafe destination. ]]>
