T09 · Insecure Skill Coding Practices
- Location
SKILL.md:74- Finding
Unrestricted URL Fetching Enables Server-Side Request Forgery
- Content
View full analysis
tuple[str, str]: """Fetch a page. Returns (html, final_url).""" try: r = requests.get(url, headers=HEADERS, timeout=8, allow_redirects=True) if r.status_code < 400: return r.text, r.url except Exception: pass return "", url ``` The vulnerable request is reached through the following contact-page logic: ```python def scrape_contact_pages(base_url: str, existing_html: str = "") -> dict: """ Scrape multiple pages for contact info. existing_html: pass HTML already fetched by website-auditor to avoid re-fetching. """ from urllib.parse import urljoin all_emails = set() all_phones = set() business_name = "" # Try homepage first (using already-fetched HTML if available) if existing_html: data = extract_from_html(existing_html) all_emails.update(data["emails"]) all_phones.update(data["phones"]) business_name = data["business_name"] # Try contact/about pages contact_paths = ["/contact", "/about", "/contact-us", "/about-us", "/get-in-touch", "/reach-us", "/find-us"] for path in contact_paths: if all_emails: break # Found emails — no need to keep crawling url = urljoin(base_url, path) html, _ = scrape_page(url) if html: data = extract_from_html(html) all_emails.update(data["emails"]) all_phones.update(data["phones"]) if not business_name: business_name = data["business_name"] ``` ### Technical Analysis The Skill accepts a `base_url`, derives additional URLs with `urljoin()`, and passes them to `requests.get()` without validating the scheme, hostname, destination port, or re ...[truncated 2302 chars]- Remediation
View remediation
