T09 · Insecure Skill Coding Practices
- Location
scripts/hxxra.py:346- Finding
Unrestricted PDF URL Fetching Enables Server-Side Request Forgery
- Content
View full analysis
Tuple[bool, str]: """ Download a PDF file. Args: url: PDF URL dest_path: Destination file path timeout: Request timeout in seconds Returns: Tuple[bool, str]: (True if successful, error message if failed) """ headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.0" } try: req = urllib.request.Request(url, headers=headers) with urllib.request.urlopen(req, timeout=timeout, context=SSL_CONTEXT) as resp: with open(dest_path, "wb") as f: shutil.copyfileobj(resp, f) ``` The attacker-controlled data reaches this function through `handle_download()`: ```python with open(from_file, "r", encoding="utf-8") as f: data = json.load(f) if isinstance(data, list): papers = data elif isinstance(data, dict) and "results" in data: papers = data["results"] # ... pdf_url = paper.get("pdf_url", "") # ... success, msg = download_pdf(pdf_url, filepath) ``` ### Technical Analysis The `download` command accepts a caller-selected JSON file and reads each paper's `pdf_url` without validating its origin. The value is passed directly to `urllib.request.urlopen()`. There are no controls restricting: - URL schemes - Destination hostnames or ports - Loopback, private, link-local, or reserved IP addresses - Cloud instance metadata endpoints - DNS rebinding - Redirect destinations - Non-academic or otherwise unexpected external hosts Consequently, a crafted search-results file can instruct the process to make requests to services reachable from the Skill's execution environment. Redirects may also be used to bypass a s ...[truncated 2051 chars]- Remediation
View remediation
