T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/news_crawler.js:9- Finding
Unrestricted Fetching of Server-Supplied URLs Enables SSRF
- Content
View full analysis
item.match(/(http.*)/)?.[0].split('\'')[0] || ''); const headers = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', 'Cache-Control': 'no-cache', 'Cookie': 'cna=DLYSGBDthG4CAbRVCNxSxGT6', 'Host': 'tv.cctv.com', 'Pragma': 'no-cache', 'Proxy-Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36' }; const data = await Promise.all(pageUrls.map(async pageUrl => { try { const pageResponse = await fetch(pageUrl, { headers }); const pageText = await pageResponse.text(); ``` The other crawler paths use the same unsafe pattern: ```javascript const pageUrls = soup.querySelectorAll('#contentELMT1368521805488378 li a') .slice(1) .map(a => a.getAttribute('href') || ''); const data = await Promise.all(pageUrls.map(async pageUrl => { try { const pageResponse = await fetch(pageUrl, { headers }); ``` ```javascript const pageUrls = soup.querySelectorAll('li a').slice(1).map(a => a.getAttribute('href') || ''); const data = await Promise.all(pageUrls.map(async pageUrl => { try { const pageResponse = await fetch(pageUrl, { headers }); ``` ### Technical Analysis The initial index requests use fixed CCTV URLs, but article URLs are subsequently extracted from remotely supplied HTML and fetched without validating their scheme, host ...[truncated 2247 chars]- Remediation
View remediation
