T09 · Insecure Skill Coding Practices
- Location
scripts/douyin.js:29- Finding
Unrestricted URL Fetching and Redirect Following Enables SSRF
- Content
View full analysis
{ const client = url.startsWith('https') ? https : http; const req = client.get(url, { headers: HEADERS }, (res) => { if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) { httpRequest(res.headers.location).then(resolve).catch(reject); return; } let data = ''; res.on('data', chunk => data += chunk); res.on('end', () => resolve(data)); }); req.on('error', reject); req.setTimeout(30000, () => { req.destroy(); reject(new Error('Request timeout')); }); }); } ``` The request destination originates directly from a command-line argument: ```js const shareUrl = process.argv[2]; if (!shareUrl) { console.error('Usage: node douyin.js '); process.exit(1); } const html = await httpRequest(shareUrl); ``` ### Technical Analysis The Skill passes an attacker-controlled URL directly to Node.js HTTP or HTTPS clients without validating its protocol, hostname, port, or resolved IP address. Despite being documented as a Douyin downloader, the implementation does not restrict requests to Douyin domains. HTTP redirects are recursively followed using the unvalidated `Location` header. Consequently, validating only the initial URL outside this function would not be sufficient: a permitted public endpoint could redirect the request to localhost, a private address, a link-local address, or another prohibited destination. The redirect implementation also lacks a redirect-count limit. A redirect loop can therefore cause repeated outbound requests and continued promise recursion until an error or resource exhaustion occurs. ### Attack Path 1. An attacke ...[truncated 1480 chars]- Remediation
View remediation
