T09 · Insecure Skill Coding Practices
- Location
scripts/feishu_docs.py:239- Finding
Arbitrary Image URL Fetching Enables SSRF and Internal Data Disclosure
- Content
View full analysis
Vulnerability Details
File Location:
scripts/feishu_docs.py, lines 239-251
Vulnerability Type: Server-Side Request Forgery (SSRF) with subsequent data upload
Risk Level: HighVulnerable code:
python # Step 2: Upload image (download if URL provided) if image_url and not image_data: img_r = requests.get(image_url, timeout=15) image_data = img_r.content if not image_data: return False, "No image data" files = {"file": ("image.png", io.BytesIO(image_data), "image/png")} data = {"file_name": "image.png", "parent_type": "docx_image", "parent_node": block_id, "size": str(len(image_data))} r2 = requests.post(f"{BASE}/drive/v1/medias/upload_all", headers={"Authorization": f"Bearer {token}"}, data=data, files=files) result2 = r2.json()Technical Analysis
The
imagecommand accepts a caller-controlled URL and passes it directly torequests.get. The implementation does not validate:- The URL scheme
- The destination hostname
- Resolved IP addresses
- Redirect destinations
- Loopback, private, link-local, or reserved address ranges
- Cloud metadata endpoints
- Response MIME type or actual file format
- Maximum response size
The request library follows redirects by default. Consequently, validating only the initial URL would also be insufficient unless every redirect destination were revalidated.
The complete response is buffered into memory through
img_r.content, labeled asimage/pngwithout format verification, and uploaded to Feishu. This creates an SSRF primitive that can turn network-reachable internal data into remotely stored content. Unbounded buffering also permits excessive memory consumption.Attack Path
- An attacker influences an Agent request or directly invokes the CLI with an image URL.
- The attacker supplies a URL targeting a local service, private network host, link-local endpoint, or a public URL that redirects to such a des ...[truncated 903 chars]
- Remediation
View remediation
Remediation Suggestions
- Permit only
httpsURLs. - Use an explicit allowlist of trusted image hosts where operationally possible.
- Resolve hostnames before connecting and reject loopback, private, link-local, multicast, unspecified, and reserved IP ranges for both IPv4 and IPv6.
- Disable redirects, or manually follow them while repeating scheme, hostname, and resolved-IP validation for every destination.
- Protect against DNS rebinding by ensuring the validated address is the address used for the connection.
- Stream the response instead of using
response.content, and enforce a strict maximum byte count. - Set both connection and read timeouts.
- Validate the response status and reject non-success responses.
- Check the declared MIME type and verify the actual image format with a safe image parser before upload.
- Abort and remove the empty image block if download, validation, upload, or binding fails.
- Permit only
