T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- scripts/utils/validator.js:3
- Finding
- Unrestricted URL Fetching Enables Private-Network Data Exfiltration<![CDATA[ ## Vulnerability Details **File Location**: `scripts/utils/validator.js:3-7`, `scripts/utils/download.js:317-331`, `scripts/video2text/index.js:96-125`, `scripts/video2text/index.js:140-146` **Vulnerability Type**: Server-Side Request Forgery with subsequent external upload **Risk Level**: High ### Vulnerable Code ```js function isUrl(url) { try { const parsedUrl = new URL(url); return parsedUrl.protocol === "http:" || parsedUrl.protocol === "https:"; } catch (_) { return false; } } ``` ```js const getRequest = (url, options) => { if (retryTimeout) { clearTimeout(retryTimeout); retryTimeout = null; } 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)); } ``` ```js const downloadResult = await helper.download(file, filepath); let tempFilePath = downloadResult?.filePath || ""; if (tempFilePath === "") { utils.printError("下载失败: 未返回文件路径"); process.exit(1); } ``` ```js 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 checks only whether the scheme is HTTP or HTTPS. It does not reject loopback addresses, RFC 1918 private addresses, link-local addresses ...[truncated 1824 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Resolve the hostname before connecting and reject every address in loopback, private, link-local, multicast, reserved, and unspecified ranges. 2. Explicitly block cloud metadata destinations, including `169.254.169.254` and IPv6 link-local equivalents. 3. Repeat destination validation after every redirect and after every DNS resolution. 4. Consider allowing only explicitly supported public video domains. 5. Protect against DNS rebinding by connecting to a previously validated address while preserving the expected TLS hostname. 6. Reject URLs containing embedded credentials or unexpected ports. 7. Do not upload downloaded content until its media type and file structure have been validated. 8. Run the downloader in a sandbox with restricted outbound network access so it cannot reach private networks. ]]>
