T09 · Insecure Skill Coding Practices
- Location
scripts/fetch_news.mjs:79- Finding
Unrestricted URL Fetching Enables Server-Side Request Forgery
- Content
View full analysis
!a.startsWith('--')); ``` ```javascript const tools = { smry: (url) => `https://smry.ai/${url}`, jina: (url) => `https://r.jina.ai/http://${url}`, '12ft': (url) => `https://12ft.io/${url}`, removepaywalls: (url) => `https://removepaywalls.com/${url}`, direct: (url) => url }; ``` ```javascript async function fetchDirect(targetUrl) { const response = await fetch(targetUrl, { headers: { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' } }); if (!response.ok) { throw new Error(`HTTP ${response.status}`); } const text = await response.text(); return { raw_content: text }; } ``` ```javascript async function tryMethod(originalUrl, methodName) { const targetUrl = tools[methodName](originalUrl); console.log(` 尝试 ${methodName}: ${targetUrl.substring(0, 60)}...`); try { let result; if (methodName === 'direct') { result = await fetchDirect(targetUrl); } else if (methodName === 'jina') { const response = await fetch(targetUrl); if (!response.ok) throw new Error(`HTTP ${response.status}`); const text = await response.text(); result = { raw_content: text }; } else { result = await extractWithTavily(targetUrl); } ``` ### Technical Analysis The first non-option command-line argument is treated as a URL and can be passed directly to `node-fetch`. The implementation does not validate: - The URL scheme. - Destination hostnames or resolved IP addresses. - Loopback, private, link-local, multicast, or reserved address ranges. - Cloud instance metadata add ...[truncated 1827 chars]- Remediation
View remediation
