T09 · Insecure Skill Coding Practices
- Location
scripts/audit-live.mjs:13- Finding
Unrestricted Live-URL Requests Permit SSRF-Style Access to Internal Services
- Content
View full analysis
Vulnerability Details
File Location:
scripts/audit-live.mjs, lines 13–19 and 24–31
Vulnerability Type: Server-Side Request Forgery (SSRF) through unrestricted URL input and redirect following
Risk Level: MediumVulnerable Code
js const base = process.argv[2]; const JSON_OUT = process.argv.includes('--json'); if (!base || !/^https?:\/\//.test(base)) { console.error('usage: node audit-live.mjs https://www.example.com [--json]'); process.exit(2); } const origin = new URL(base).origin; async function get(path) { try { const r = await fetch(origin + path, { redirect: 'follow', headers: { 'user-agent': 'seo-audit/1.0' } }); const text = await r.text(); return { status: r.status, headers: r.headers, text }; } catch (e) { return { status: 0, headers: new Headers(), text: '', error: String(e) }; } }Technical Analysis
The live auditor accepts any syntactically valid HTTP or HTTPS URL. It does not verify that the destination is a public website or reject loopback, private, link-local, IPv6-local, or cloud instance-metadata addresses.
The use of
redirect: 'follow'creates an additional bypass: an initially public URL can redirect requests to a prohibited internal address. Because redirect destinations are not manually inspected and validated, validating only the original hostname would not be sufficient.The script issues GET requests for the following fixed paths:
/robots.txt/sitemap.xml/llms.txt/
It reads complete response bodies and uses response status, headers, robots policies, sitemap contents, canonical tags, and JSON-LD data to produce its report. This provides an attacker with limited probing capability against services accessible from the Agent's network environment.
The network access itself is necessary for the declared live SEO audit. However, access to arbitrary internal destinations exceeds the minimum privileges needed to aud ...[truncated 1536 chars]
- Remediation
View remediation
Remediation Suggestions
-
Require HTTPS by default. Reject plain HTTP unless the user explicitly enables a documented local-development mode.
-
Reject non-public destinations. Resolve the hostname and block all loopback, private, link-local, multicast, unspecified, and reserved IPv4 and IPv6 ranges. At minimum, cover:
127.0.0.0/810.0.0.0/8172.16.0.0/12192.168.0.0/16169.254.0.0/160.0.0.0/8- IPv6 loopback
::1 - IPv6 link-local
fe80::/10 - IPv6 unique-local
fc00::/7 - IPv4-mapped IPv6 equivalents
- Known cloud metadata destinations
-
Handle redirects manually. Set
redirect: 'manual', impose a small redirect limit, resolve everyLocationheader, and repeat scheme, hostname, port, and resolved-address validation before each request. -
Mitigate DNS rebinding. Validate all resolved addresses immediately before connecting. Where feasible, pin the validated address for the request rather than allowing a second uncontrolled DNS resolution.
-
Restrict ports. Permit only standard public web ports such as 443 by default. Require explicit user confirmation for nonstandard ports.
-
Limit resource consumption. Add request timeouts, maximum response-body sizes, and content-type checks before reading full bodies.
-
Require explicit authorization for private audits. If auditing internal or local sites is a legitimate use case, place it behind an explicit flag such as
--allow-private-networkand display a warning describing the expanded network privilege. -
Add regression tests. Verify rejection of direct private addresses, alternative numeric IP representations, IPv4-mapped IPv6 addresses, and public-to-private redirect chains.
-
