T09 · Insecure Skill Coding Practices
- Location
scripts/feishu_send_video.py:139- Finding
Arbitrary URL Fetching Enables SSRF and Potential Forwarding of Internal Resources
- Content
View full analysis
Path: parsed = urlparse(url) suffix = Path(parsed.path).suffix.lower() if suffix not in VIDEO_EXTENSIONS: suffix = ".mp4" fd, tmp_name = tempfile.mkstemp(prefix="_ovvideo_", suffix=suffix) os.close(fd) tmp_path = Path(tmp_name) with requests.get(url, stream=True, timeout=300) as resp: resp.raise_for_status() with tmp_path.open("wb") as f: for chunk in resp.iter_content(chunk_size=1 << 20): if chunk: f.write(chunk) if tmp_path.stat().st_size == 0: tmp_path.unlink(missing_ok=True) raise RuntimeError(f"Downloaded empty file from: {url}") return tmp_path ``` The downloaded response is later uploaded to Feishu and sent to the selected recipient: ```python if args.url: downloaded_path = download_video(args.url) file_path = downloaded_path else: file_path = Path(args.file) ``` ```python file_key = upload_video(token, file_path) result = send_video_message( token, receive_id, receive_id_type, file_key, image_key ) ``` ### Technical Analysis The caller can provide an arbitrary value to `--url`. The implementation parses the path only to derive a filename extension and then passes the URL directly to `requests.get`. It does not validate: - The URL scheme. - Embedded URL credentials. - The destination hostname. - DNS-resolved IP addresses. - Loopback, private, link-local, multicast, or reserved network ranges. - Redirect destinations. The `requests` library follows redirects by default. Therefore, even an initially public URL can redirect the Agent to an internal address. Assigning an `.mp4` suffi ...[truncated 1934 chars]- Remediation
View remediation
