T09 · Insecure Skill Coding Practices
- Location
scripts/repurpose.py:38- Finding
Unrestricted URL Fetching Enables Server-Side Request Forgery and Local Resource Access
- Content
View full analysis
dict: """Extract article content from a URL.""" if not HAS_BS4: print("beautifulsoup4 required for URL mode. Install: pip install beautifulsoup4", file=sys.stderr) sys.exit(1) req = Request(url, headers={"User-Agent": USER_AGENT}) try: with urlopen(req, timeout=30) as resp: encoding = resp.headers.get_content_charset() or "utf-8" html = resp.read().decode(encoding, errors="replace") except (HTTPError, URLError) as e: print(f"Error fetching URL: {e}", file=sys.stderr) sys.exit(1) ``` ### Technical Analysis The command-line `url` argument is passed directly to `urllib.request.Request` and `urlopen` without validating the URL scheme, destination hostname, resolved IP address, port, or redirect destination. Consequently, an attacker who can invoke the skill may cause requests to destinations available from the execution environment but unavailable from the attacker's own network position. Potential targets include: - Loopback services such as `127.0.0.1` or `::1` - RFC 1918 private-network services - Link-local addresses and cloud metadata endpoints - Internal hostnames resolved through the host's DNS configuration - Public endpoints that redirect to an internal destination - Non-HTTP resources supported by `urllib`, including direct `file:` URLs in applicable runtime configurations The response is decoded without checking its content type or size. BeautifulSoup then extracts its title, description, and body, portions of which are returned through generated posts or JSON output. This creates an information-disclosure channel in addition to the network request primitive. ### Attack Path 1. An attacker supplies a craf ...[truncated 1656 chars]- Remediation
View remediation
