T09 · Insecure Skill Coding Practices
- Location
datascraping.py:11- Finding
Unrestricted User-Controlled URL Fetching Enables Server-Side Request Forgery
- Content
View full analysis
1: topic_url = sys.argv[1].rstrip('/') else: topic_url = input("Enter the Lowyat forum topic URL: ").strip().rstrip('/') # Extract topic ID from URL topic_id = topic_url.split('/')[-1].split('/')[0] output_file = f'{topic_id}.xlsx' print(f"Scraping topic: {topic_id}") # Fetch first page to auto-detect total pages r = requests.get(topic_url) soup = BeautifulSoup(r.content, 'html5lib') ``` The same unvalidated destination is subsequently used for pagination: ```python for offset in tqdm(offsets, desc="Scraping", unit="page", dynamic_ncols=True): url = topic_url + '/+' + offset if offset else topic_url r = requests.get(url) ``` ### Technical Analysis The script accepts a URL directly from a command-line argument or interactive input and passes it to `requests.get()` without enforcing the documented `forum.lowyat.net` destination. There is no validation of: - The URL scheme. - The exact hostname. - Explicit URL credentials or nonstandard ports. - Loopback, private, link-local, or reserved destination addresses. - DNS resolution results. - Redirect destinations. - Response size or request timeout. Python Requests follows redirects by default. Consequently, validating only the initial URL would also be insufficient unless every redirect target were independently checked. Although the skill documentation says that the script is intended to access Lowyat Forum, this restriction is not implemented in the code. A caller can therefore cause the host executing the skill to send requests to arbitrary HTTP endpoints reachable from its network context. ### Attack Path 1. An attacker persuades the user or Agent to run the scraper with an attacker-selected URL. 2. The supplied URL ...[truncated 1657 chars]- Remediation
View remediation
