T09 · Insecure Skill Coding Practices
- Location
scripts/web_reader_pro.py:623- Finding
Unrestricted URL Fetching Enables SSRF and Disclosure of Sensitive URLs to Jina
- Content
View full analysis
Tuple[str, str]: """ Extract using Jina Reader API. """ api_key = os.environ.get('JINA_API_KEY') if not api_key: raise ValueError("JINA_API_KEY not set") # Use Jina's reader API jina_url = f"https://r.jina.ai/{url}" headers = { 'Authorization': f'Bearer {api_key}', 'X-Return-Format': 'markdown', } response = requests.get(jina_url, headers=headers, timeout=30) response.raise_for_status() ``` ```python def _extract_webfetch(self, url: str) -> Tuple[str, str]: """ Extract using basic HTTP request + HTML parsing. Fallback method when other tiers fail. """ headers = { 'User-Agent': 'Mozilla/5.0 (compatible; WebReaderPro/1.0)', 'Accept': 'text/html,application/xhtml+xml', } response = requests.get(url, headers=headers, timeout=15) response.raise_for_status() ``` ### Technical Analysis The public fetching methods accept caller-controlled URLs without validating the URL scheme, hostname, resolved address, port, embedded credentials, or redirect destination. The direct WebFetch tier passes the URL directly to `requests.get()`. Consequently, the process can be induced to connect to loopback, private-network, link-local, or other reserved destinations reachable from its execution environment. Python Requests also follows redirects by default, so validating only an initial URL would not be sufficient. The Jina tier constructs `https://r.jina.ai/{url}` using the complete caller-provided value. This discloses the target URL to a third-party service. If the URL includes signed query parameters, capability tokens, session identifiers, private document paths, or other sensitive valu ...[truncated 2173 chars]- Remediation
View remediation
