T09 · Insecure Skill Coding Practices
- Location
scripts/preprocess-rss-sitemap.js:97- Finding
Unrestricted URL Fetching Enables Server-Side Request Forgery
- Content
View full analysis
controller.abort(), timeoutMs); try { const response = await fetch(url, { redirect: "follow", signal: controller.signal, headers: { "accept": "application/xml,text/xml,application/rss+xml,application/atom+xml,text/plain;q=0.8,*/*;q=0.2", "user-agent": "rss-sitemap-skill/1.0", }, }); const body = await response.text(); return { url, finalUrl: response.url || url, status: response.status, ok: response.ok, contentType: response.headers.get("content-type") || "", body, }; } finally { clearTimeout(timer); } } ``` Attacker-controlled sitemap directives in `robots.txt` are accepted as additional targets: ```js async function discoverRobotsSitemaps(origin, timeoutMs) { const robotsUrl = `${origin}/robots.txt`; const response = await fetchText(robotsUrl, timeoutMs); if (!response.ok) { return { resource: responseSummary(response, "robots"), urls: [] }; } const urls = []; for (const line of response.body.split(/\r?\n/)) { const match = line.match(/^\s*sitemap\s*:\s*(\S+)\s*$/i); if (match) { urls.push(normalizeUrl(match[1], origin)); } } return { resource: responseSummary(response, "robots"), urls: unique(urls) }; } ``` Nested sitemap locations are recursively fetched without restricting them to the original host: ```js async function processResource(url ...[truncated 3149 chars]- Remediation
View remediation
