T09 · Insecure Skill Coding Practices
- Location
- scripts/utils/validator.js:3
- Finding
- Arbitrary URL Fetching Enables Server-Side Request Forgery<![CDATA[ ## Vulnerability Details **File Location**: `scripts/utils/validator.js:3-8`, `scripts/video2text/index.js:96-113`, `scripts/utils/download.js:317-331` **Vulnerability Type**: Server-Side Request Forgery through insufficient URL validation **Risk Level**: High ### Complete Code Snippet ```javascript // scripts/utils/validator.js:3-8 function isUrl(url) { try { const parsedUrl = new URL(url); return parsedUrl.protocol === "http:" || parsedUrl.protocol === "https:"; } catch (_) { return false; } } ``` ```javascript // 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); } ``` ```javascript // scripts/utils/download.js:317-331 const req = this.__protocol.request(options, (response) => { if (this.__isRequireRedirect(response)) { redirectCount++; if (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, url).href; this.emit("redirected", redirectedURL, url); return getRequest(redirectedURL, getReqOptions(redirectedURL)); } ``` ### Technical Analysis The URL validator verifies only that the input uses the HTTP or HTTPS scheme. It does not resolve and inspect the destination address or reject loopback, private, link-local, reserved, or cloud metadata address rang ...[truncated 1957 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Permit HTTPS only unless HTTP support is strictly required. 2. Resolve the hostname before connecting and reject all loopback, private, link-local, multicast, reserved, and unspecified IPv4 and IPv6 ranges. 3. Explicitly block common metadata destinations, including `169.254.169.254`, but do not rely on a hostname or single-address blocklist alone. 4. Re-resolve and validate every redirect target before following it. 5. Protect against DNS rebinding by connecting to a validated, pinned address while preserving the expected TLS hostname. 6. Consider an allowlist of supported public media platforms and trusted content-delivery domains. 7. Reject URLs containing embedded credentials or unexpected ports. 8. Apply the same policy to preliminary requests, retries, resumed downloads, and redirects. 9. Run the downloader in a network-restricted sandbox that cannot access loopback, private networks, or metadata services. ]]>
