T09 · Insecure Skill Coding Practices
- Location
scripts/foto_webcam_snapshot.py:38- Finding
Server-Side Request Forgery Through Unrestricted Webcam URLs
- Content
View full analysis
str: r = requests.get(page_url, headers={"User-Agent": UA, "Accept": "text/html"}, timeout=30) r.raise_for_status() html = r.text ``` ```python def download_image(url: str) -> bytes: r = requests.get(url, headers={"User-Agent": UA, "Accept": "image/avif,image/webp,image/apng,image/*,*/*"}, timeout=30) r.raise_for_status() return r.content ``` ```python page_url = a.url fav_name = None fav_id = a.id source_url = None if a.favorites and a.id is not None: fav = read_favorites(a.favorites) items = fav.get("items") or [] hit = next((it for it in items if int(it.get("id")) == int(a.id)), None) if not hit: raise RuntimeError(f"Favorite id not found: {a.id}") fav_name = hit.get("name") page_url = hit.get("page") source_url = hit.get("image") if not page_url: raise RuntimeError("Missing --url or --favorites+--id") if not source_url: source_url = resolve_current_image_from_page(page_url) ``` ### Technical Analysis The script passes URLs from the `--url` argument and from the `page` or `image` properties of a favorites file directly to `requests.get()`. It does not validate the URL scheme, destination hostname, resolved IP address, port, or redirect targets. Consequently, a caller able to control the URL or favorites data can make the process issue requests to loopback addresses, private network ranges, link-local services, or cloud instance metadata endpoints. The `requests` library follows redirects by default, so checking only an initial hostname would not be sufficient. In addition, the g ...[truncated 1339 chars]- Remediation
View remediation
