T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/utils/validator.js:3
- Finding
- Unrestricted URL Fetching Enables Internal Resource Access and Exfiltration<![CDATA[ ## Vulnerability Details **File Location**: `scripts/utils/validator.js:3-9`, `scripts/video2text/index.js:95-134`, `scripts/utils/download.js:479-493` **Vulnerability Type**: Server-Side Request Forgery (SSRF) with subsequent data upload **Risk Level**: High ### Vulnerable Code `scripts/utils/validator.js:3-9`: ```js function isUrl(url) { try { const parsedUrl = new URL(url); return parsedUrl.protocol === "http:" || parsedUrl.protocol === "https:"; } catch (_) { return false; } } ``` `scripts/video2text/index.js:95-134`: ```js 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); } // 下载文件缺少扩展名时统一补 .mp4,便于服务端识别视频类型 if (tempFilePath.indexOf(".") === -1) { try { fs.renameSync(tempFilePath, tempFilePath + ".mp4"); tempFilePath += ".mp4"; } catch (renameError) { utils.printWarn("文件重命名失败: " + renameError.message); } } utils.printInfo("网络视频已下载到本地: " + tempFilePath); file = tempFilePath; } catch (error) { utils.printError("下载失败: " + (error.message || String(error))); process.exit(1); } } else if (!validator.isFilePath(file)) { utils.printError("无效的文件路径或URL"); process.exit(1); } if (!fs.existsSync(file)) { utils.printError("文件不存在: " + file); process.exit(1); } ``` `scripts/utils/download.js:479-493`: ```js 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.e ...[truncated 2562 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Permit only HTTPS URLs unless plain HTTP is explicitly required and approved. 2. Resolve the hostname before connecting and reject all loopback, private, link-local, multicast, reserved, and unspecified IPv4 and IPv6 ranges. 3. Explicitly block cloud metadata addresses, including `169.254.169.254` and platform-specific metadata hostnames. 4. Repeat full validation after every redirect. 5. Verify the actual socket address after connection to prevent DNS rebinding and time-of-check/time-of-use bypasses. 6. Normalize and validate IPv4-mapped IPv6 addresses, integer IP representations, and alternate encodings. 7. Consider an allowlist of supported public video platforms and content-delivery domains. 8. Require explicit user confirmation before uploading content retrieved from a URL outside the expected domain set. 9. Add tests covering direct private addresses, redirect-based SSRF, DNS rebinding, IPv6 local addresses, and metadata endpoints. ]]>
