T09 · Insecure Skill Coding Practices
- Location
scripts/monitor.js:23- Finding
Configuration-Controlled Server-Side Request Forgery
- Content
View full analysis
Vulnerability Details
File Location:
scripts/monitor.js, lines 23-30 and 64-67
Vulnerability Type: Server-Side Request Forgery (SSRF)
Risk Level: HighVulnerable Code
javascript async function fetchWebsite(url) { return new Promise((resolve, reject) => { https.get(url, { timeout: 10000 }, (res) => { let data = ''; res.on('data', chunk => data += chunk); res.on('end', () => resolve(data)); }).on('error', reject); }); }The unvalidated URL is passed to this function from the configuration:
javascript async function createSnapshot(competitor) { try { console.log(`📸 Snapshotting ${competitor.name} (${competitor.url})...`); const html = await fetchWebsite(competitor.url); const content = extractContent(html);Technical Analysis
The application reads competitor URLs from
competitors.jsonand supplies them directly tohttps.get. It does not validate the destination hostname, port, resolved IP address, or network range.Requiring HTTPS does not prevent SSRF. An attacker who can create or modify the configuration can target HTTPS services bound to loopback addresses, private networks, or other infrastructure reachable from the monitoring host. The fetched response is processed to extract titles, headings, prices, content length, and a content hash, after which those values are written to snapshots and reports.
Attack Path
- An attacker obtains the ability to create or modify the configuration supplied to the monitor.
- The attacker adds a competitor whose URL points to an internal HTTPS endpoint, such as a loopback or private-network service.
- A user or scheduled cron task executes
node scripts/monitor.js monitor. - The process requests the internal endpoint using the monitoring host's network access.
- Extracted response information is saved under
snapshots/and may subsequently appear in generated ...[truncated 696 chars]
- Remediation
View remediation
Remediation Suggestions
- Parse each URL with the standard
URLclass and reject malformed URLs. - Permit only
https:and approved destination ports. - Require an explicit allowlist of competitor domains where feasible.
- Resolve hostnames before making requests and reject loopback, private, link-local, multicast, unspecified, and reserved IPv4 and IPv6 ranges.
- Protect against DNS rebinding by verifying the address actually used for the connection, not only an earlier DNS lookup.
- If redirect support is later added, apply the same validation to every redirect target.
- Run the monitor in a restricted environment without access to sensitive internal networks.
- Validate the configuration against a strict schema before monitoring begins.
- Parse each URL with the standard
