T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/arxiv_html_static_builder.py:128
- Finding
- Unrestricted Asset Retrieval Enables Server-Side Request Forgery<![CDATA[ ## Vulnerability Details **File Location**: `scripts/arxiv_html_static_builder.py:128-147` **Vulnerability Type**: Server-Side Request Forgery and unrestricted network access **Risk Level**: High ### Vulnerable Code ```python def download_asset(url, assets_dir, manifest): if not url or url.startswith(("data:", "javascript:", "mailto:", "#")): return url if url in manifest: return manifest[url]["local"] try: resp = requests.get(url, headers={"User-Agent": USER_AGENT}, timeout=40) resp.raise_for_status() except Exception as exc: print(f"Asset fetch failed: {url}: {exc}", file=sys.stderr) return url filename = safe_asset_name(url, resp.headers.get("content-type", "")) local_path = assets_dir / filename local_path.write_bytes(resp.content) manifest[url] = { "url": url, "local": f"assets/{filename}", "bytes": len(resp.content), "content_type": resp.headers.get("content-type", ""), } return manifest[url]["local"] ``` Remote HTML and CSS supply URLs to this function through the following asset-rewriting operations: ```python for tag in soup.find_all(src=True): tag["src"] = download_asset(urljoin(base_url, tag["src"]), assets_dir, manifest) for tag in soup.find_all(srcset=True): tag["srcset"] = rewrite_srcset(tag["srcset"], base_url, assets_dir, manifest) for tag in soup.find_all(href=True): rel = {r.lower() for r in tag.get("rel", [])} if tag.get("rel") else set() should_fetch = tag.name == "link" and ("stylesheet" in rel or "icon" in rel or "preload" in rel) if tag.name in {"image", "use"}: should_fetch = True if should_fetch: abs_url = urljoin(base_url, tag["href"]) ``` ### Technical Analysis The Skill legitimately requires outbound network access to obtain an arXiv paper and its assets. However, the implementation does not restrict asset requests to arXiv-controlled hosts. Every supported ` ...[truncated 2655 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Restrict downloadable assets to an explicit allowlist of trusted HTTPS hosts required for arXiv content. 2. Reject all schemes other than `https`. 3. Resolve each hostname before connecting and reject loopback, private, link-local, multicast, reserved, unspecified, and metadata-service addresses for both IPv4 and IPv6. 4. Disable automatic redirects or validate every redirect target using the same scheme, hostname, and resolved-address policy. 5. Stream responses instead of reading `resp.content` at once, and enforce strict per-file and aggregate download-size limits. 6. Limit the number of assets and CSS recursion depth processed for one paper. 7. Validate response MIME types against the expected resource category. 8. Apply equivalent validation to initial HTML, PDF, stylesheet, CSS asset, `srcset`, SVG, preload, and icon requests. 9. Fail closed rather than retaining a disallowed remote URL in generated HTML. 10. Where possible, use a network sandbox that permits access only to approved arXiv infrastructure. ]]>
