T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/utils/validator.js:3
- Finding
- Arbitrary URL Fetching Enables SSRF and External Data Relay<![CDATA[ ## Vulnerability Details **File Locations**: - `scripts/utils/validator.js:3-7` - `scripts/video2text/index.js:96-108` - `scripts/utils/download.js:323-331` - `scripts/video2text/index.js:140-146` **Vulnerability Type**: Server-Side Request Forgery (SSRF) with response exfiltration **Risk Level**: High ### Vulnerable Code ```js // scripts/utils/validator.js:3-7 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-108 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); ``` ```js // scripts/utils/download.js:323-331 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)); } ``` ```js // scripts/video2text/index.js:140-146 const presignedUrl = await video.getPresignedUrl(tokenValue, file); if (!presignedUrl || !presignedUrl?.url || presignedUrl.url === "") { throw new Error("获取预签名URL失败,请反馈给开发者"); } utils.printInfo("上传文件到安全空间..."); await upload.uploadFileToOSS(file, presignedUrl.url, presignedUrl.headers); ``` ### Technical Analysis The URL validator verifies only that the input uses the `http:` or `https:` scheme. It does not resolve or ...[truncated 2389 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Accept HTTPS URLs only unless plain HTTP is explicitly required and approved. 2. Resolve the destination hostname before connecting and reject every address in loopback, private, link-local, multicast, reserved, and cloud-metadata ranges for both IPv4 and IPv6. 3. Apply the same validation to every redirect target before following it. 4. Prevent HTTPS-to-HTTP redirect downgrades. 5. Consider allowlisting supported video-hosting domains rather than accepting arbitrary hosts. 6. Restrict destination ports to expected web ports. 7. Protect against DNS rebinding by ensuring the validated address is the address used for the connection. 8. Enforce maximum response size and download duration before writing the complete response to disk. 9. Verify the response MIME type and file signature against an allowlist of supported video formats before upload. 10. Abort and delete the temporary file if any validation fails. ]]>
