T09 · Insecure Skill Coding Practices
- Location
scripts/image_recognize.py:96- Finding
Server-Side Request Forgery and Unbounded Remote Image Download
- Content
View full analysis
Vulnerability Details
File Location:
scripts/image_recognize.py:96-101
Vulnerability Type: Server-Side Request Forgery (SSRF), unintended third-party data disclosure, and unbounded response buffering
Risk Level: MediumVulnerable Code
python # 处理网络 URL if value.startswith(("http://", "https://")): try: response = requests.get(value, timeout=30) response.raise_for_status() return base64.b64encode(response.content).decode() except requests.RequestException as e: raise Exception(f"下载网络图片失败: {e}")The downloaded content is later transmitted to the external recognition service:
python payload = { "image_b64": image_b64 } try: response = requests.post(api_url, json=payload, headers=headers, timeout=30)Technical Analysis
The Skill intentionally supports remote image URLs, but it fetches a user-controlled HTTP or HTTPS destination without validating the destination host or resolved IP address. It does not reject loopback, link-local, private, reserved, multicast, or cloud metadata addresses.
The
requestslibrary follows redirects by default. Consequently, checking only the original string for anhttp://orhttps://prefix does not prevent an initially public URL from redirecting to an internal service. DNS rebinding and resolution changes may also bypass simplistic hostname-based controls unless the resolved address used for the connection is validated.The response is loaded in full through
response.contentbefore encoding. No response-size limit, content-type validation, or image decoding check is enforced. This contradicts the documented 4 MB image constraint and allows excessive memory consumption.After retrieval, the response bytes are Base64-encoded and submitted to Baidu's Qianfan endpoint by
recognize_image. Encoding does not provide confidentiality or sanitization. If the URL resolves to a sensitive internal resource, its response content may therefore ...[truncated 2120 chars]- Remediation
View remediation
Remediation Suggestions
- Permit remote fetching only when required. For higher-assurance deployments, require callers to upload local image bytes rather than allowing arbitrary URLs.
- Resolve the destination before connecting and reject all loopback, private, link-local, multicast, unspecified, reserved, and cloud metadata addresses for both IPv4 and IPv6.
- Disable automatic redirects with
allow_redirects=False, or validate the scheme, hostname, resolved address, and port at every redirect hop. - Defend against DNS rebinding by ensuring the validated address is the address actually used for the connection. Avoid relying solely on hostname string checks.
- Use streaming downloads and enforce a strict byte limit, such as the documented 4 MB maximum. Abort immediately when
Content-Lengthexceeds the limit or when streamed bytes cross it. - Allow only expected image media types, reject ambiguous or missing content types as appropriate, and verify the downloaded bytes with a trusted image decoder before forwarding them.
- Restrict destination ports to those required for image retrieval, normally TCP 80 and 443.
- Apply network-level egress controls that prevent the Skill process from reaching internal networks, metadata services, and administrative endpoints.
- Obtain explicit user consent before sending image content to the third-party recognition provider, particularly where images may contain personal or confidential information.
- Add tests covering direct private addresses, IPv6 loopback, numeric-IP representations, public-to-private redirects, DNS rebinding scenarios, non-image responses, oversized bodies, and chunked responses without
Content-Length.
