T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/convert.js:260
- Finding
- Unrestricted Remote Image Fetching Enables Server-Side Request Forgery and Denial of Service## Vulnerability Details **File Location**: `scripts/convert.js`, lines 260-264 **Vulnerability Type**: Server-Side Request Forgery (SSRF) and unbounded network resource consumption **Risk Level**: High ```javascript if (imageUrl.startsWith('http://') || imageUrl.startsWith('https://')) { // 网络图片 const response = await fetch(imageUrl); const arrayBuffer = await response.arrayBuffer(); imageBuffer = Buffer.from(arrayBuffer); } ``` ### Technical Analysis An image URL taken directly from the Markdown syntax tree is passed to `fetch()` without security restrictions. Although downloading remote images is part of the declared functionality, the implementation does not: - Restrict destination hosts or ports. - Reject loopback, private, link-local, or cloud metadata addresses. - Validate destinations after DNS resolution. - Validate every HTTP redirect destination. - Enforce a request timeout. - Limit the downloaded response size. - Check the HTTP response status. - Verify that the response is a supported image through its MIME type and file signature. Consequently, an attacker who controls the Markdown input can cause the converter to send requests from the host running the Skill. This exceeds the minimum network privilege needed to retrieve ordinary public images. ### Attack Path 1. An attacker prepares a Markdown document containing an image URL that targets an internal service, a loopback endpoint, a link-local metadata endpoint, or an attacker-controlled redirect. 2. A user invokes the converter on that document. 3. The parser places the attacker-controlled URL in `node.url`. 4. `convertImage()` passes the URL directly to `fetch()`. 5. The request originates from the converter host and can reach resources unavailable to the attacker. 6. The response is fully buffered in memory and passed to DOCX generation. Depending on the content and library behavior, this can expose returned data through th ...[truncated 686 chars]
- Remediation
- ## Remediation Suggestions - Permit remote retrieval only when explicitly enabled by the user. - Prefer an allowlist of approved HTTPS hosts; reject plain HTTP unless there is a documented requirement. - Resolve hostnames before connecting and reject loopback, private, link-local, multicast, reserved, and cloud metadata address ranges for both IPv4 and IPv6. - Disable redirects or validate the resolved destination of every redirect hop. - Protect against DNS rebinding by connecting only to the validated resolved address while preserving correct TLS hostname verification. - Enforce strict connection and total-request timeouts with cancellation. - Stream responses while applying a small maximum byte limit instead of calling `arrayBuffer()` without bounds. - Require a successful HTTP status and validate both the declared MIME type and image file signature. - Run conversion in a sandbox with restricted outbound networking when processing untrusted Markdown.
