T09 · Insecure Skill Coding Practices
- Location
scripts/fetch.py:132- Finding
Unrestricted Server-Side Request Forgery and Redirect-Based Allowlist Bypass
- Content
View full analysis
bool: """Check whether the domain is on the allowlist.""" if not ALLOWED_DOMAINS: return True parsed = urlparse(url) allowed = [d.strip() for d in ALLOWED_DOMAINS.split(",")] return parsed.netloc in allowed or any( parsed.netloc.endswith("." + d) for d in allowed ) ``` ```python def fetch_remote(url: str, max_chars: int = DEFAULT_MAX_CHARS) -> dict: """Remote cleaning mode using Jina Reader.""" try: clean_url = url.replace("https://", "").replace("http://", "") jina_url = JINA_READER_URL.format(url=clean_url) response = requests.get(jina_url, timeout=30) response.raise_for_status() ``` ```python def fetch_local(url: str, max_chars: int = DEFAULT_MAX_CHARS) -> dict: """Local parsing mode.""" try: headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' } response = requests.get(url, headers=headers, timeout=30) response.raise_for_status() content = clean_html_local(response.text, max_chars) ``` ```python use_remote = args.remote or (DEFAULT_MODE == "remote" and not args.local) if use_remote: result = fetch_remote(url, args.max_chars) if not result["success"]: print( f"Remote fetch failed: {result['error']}, falling back to local...", file=sys.stderr ) result = fetch_local(url, args.max_chars) else: result = fetch_local(url, args.max_chars) ``` ### Technical Analysis The Skill accepts a caller-provided URL and issues an HTTP request from the Agent environment. When `ALLOWED_DOMAINS ...[truncated 3574 chars]- Remediation
View remediation
