T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/utils/validator.js:3
- Finding
- Unrestricted URL Fetching Enables SSRF and Internal Service Data Exfiltration<![CDATA[ ## Vulnerability Details **File Location**: `scripts/utils/validator.js:3-9`, `scripts/video2text/index.js:96-113`, and `scripts/utils/download.js:478-492` **Vulnerability Type**: Server-Side Request Forgery (SSRF) through unrestricted URL downloads and redirects **Risk Level**: High ### Vulnerable Code ```js // scripts/utils/validator.js:3-9 function isUrl(url) { try { const parsedUrl = new URL(url); return parsedUrl.protocol === "http:" || parsedUrl.protocol === "https:"; } catch (_) { return false; } } ``` ```js // scripts/video2text/index.js:96-113 if (validator.isUrl(file)) { const filepath = utils.downloadPath(); try { await fs.promises.mkdir(filepath, { recursive: true }); } catch (error) { utils.printError("临时下载目录创建失败: " + (error.message || String(error))); process.exit(1); } try { const downloadResult = await helper.download(file, filepath); let tempFilePath = downloadResult?.filePath || ""; if (tempFilePath === "") { utils.printError("下载失败: 未返回文件路径"); process.exit(1); } ``` ```js // scripts/utils/download.js:478-492 if (this.__isRequireRedirect(response)) { this.__redirectCount++; if (this.__redirectCount > this.__opts.maxRedirects) { const err = new Error("Too many redirects"); this.__setState(this.__states.FAILED); this.emit("error", err); return reject(err); } const redirectedURL = /^https?:\/\//.test(response.headers.location) ? response.headers.location : new URL(response.headers.location, this.url).href; this.__isRedirected = true; this.__initProtocol(redirectedURL); this.emit("redirected", redirectedURL, this.url); return this.__start(); } ``` ### Technical Analysis The URL validator verifies only whether the supplied URL uses HTTP or HTTPS. It does not reject destinations resolving to loopback, private, link-local, reserved, multicast, or cloud metadata address ranges. Examples of potentially reachable destinations inc ...[truncated 2048 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Resolve the destination hostname before making a request and reject all non-public IPv4 and IPv6 addresses. 2. Explicitly block loopback, private, link-local, multicast, reserved, carrier-grade NAT, and cloud metadata ranges. 3. Apply the same validation to every redirect before following it. 4. Limit redirects to the supported protocols and a small maximum count. 5. Defend against DNS rebinding by connecting only to an address that was resolved and approved during validation, while preserving correct TLS hostname verification. 6. Prefer an allowlist of supported public media domains if the Skill is intended for specific platforms. 7. Reject URLs containing unexpected credentials or ports. 8. Impose strict response-size, download-time, and media-type limits before writing or uploading content. 9. Validate that downloaded content is an expected media format before sending it to the remote service. 10. Add automated tests for direct and redirected access to IPv4, IPv6, loopback, private-network, and metadata endpoints. ]]>
