T09 · Insecure Skill Coding Practices
- Location
scripts/export_webpage.py:21- Finding
Unrestricted URL Handling Enables SSRF and Local File Disclosure
- Content
View full analysis
str: result = run(['curl', '-L', '--max-time', '30', '-A', UA, url]) return result.stdout ``` The same unvalidated URL is also passed to Chrome: ```python def fetch_rendered_dom(url: str, virtual_time_budget: int) -> str: chrome = chrome_path() if not chrome: raise RuntimeError('未找到 Chrome/Chromium,无法获取浏览器渲染后的 DOM') result = run([ chrome, '--headless=new', '--disable-gpu', '--no-first-run', f'--virtual-time-budget={virtual_time_budget}', '--dump-dom', url, ]) return result.stdout ``` It is additionally passed to Playwright: ```python const url = process.argv[1]; const out = process.argv[2]; const chrome = process.env.CHROME_BIN; const { chromium } = require('playwright'); const browser = await chromium.launch({ headless: true, executablePath: chrome }); const page = await browser.newPage(); await page.goto(url, { waitUntil: 'networkidle', timeout: 45000 }); ``` The initial fetch is invoked directly using the command-line argument: ```python raw = fetch_html(args.url) browser_text_temp = outdir / '.browser_text_tmp.json' doc = extract(args.url, raw, not args.disable_browser_fallback, args.virtual_time_budget, browser_text_temp=browser_text_temp) ``` ### Technical Analysis The user-controlled URL is passed directly to `curl`, Chrome, and Playwright without validation of: - URL scheme - Destination hostname or resolved IP address - Destination port - Redirect destinations - Loopback, link-local, private, multicast, or reserved address ranges - Local-file schemes - DNS rebinding or resolution changes The `cu ...[truncated 2313 chars]- Remediation
View remediation
