T09 · Insecure Skill Coding Practices
- Location
scripts/extract-design.mjs:16- Finding
Unrestricted URL Navigation Enables SSRF and Local-File Access
- Content
View full analysis
Vulnerability Details
File Location:
scripts/extract-design.mjs:16-36
Vulnerability Type: Server-Side Request Forgery and unrestricted local-resource navigation
Risk Level: Medium
Category: T09: Insecure Skill Coding PracticesVulnerable Code
js const options = parseArgs(process.argv.slice(2)); if (!options.url) { fail('Missing --url. Example: node scripts/extract-design.mjs --url https://example.com --out ./design.md'); } const outPath = resolve(process.cwd(), options.out ?? 'design.md'); const snapshotPath = options.snapshot ? resolve(process.cwd(), options.snapshot) : undefined; const viewport = parseViewport(options.viewport ?? '1440x900'); const timeoutMs = Number(options.timeout ?? 30000); const executablePath = options['executable-path'] ?? process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH ?? findBrowserExecutable(); const browser = await chromium.launch({ headless: true, ...(executablePath ? { executablePath } : {}), }); try { const page = await browser.newPage({ viewport }); await page.goto(options.url, { waitUntil: 'domcontentloaded', timeout: timeoutMs });The documented workflow also explicitly permits unrestricted local-file URLs:
bash node scripts/extract-design.mjs --url file:///absolute/path/to/page.html --out ./design.md --snapshot ./design-snapshot.jsonThis behavior appears at
SKILL.md:31-34.Technical Analysis
The command-line
--urlvalue is supplied directly to Playwright'spage.goto()without URL parsing, protocol allowlisting, hostname validation, IP-address filtering, DNS resolution checks, or redirect validation.Consequently, the browser may navigate to:
- Loopback services such as
http://127.0.0.1orhttp://localhost. - Private-network systems in RFC 1918 address ranges.
- Link-local services, including cloud metadata endpoints such as
169.254.169.254. - Arbitrary
file:URLs accessib ...[truncated 2710 chars]
- Loopback services such as
- Remediation
View remediation
Remediation Suggestions
- Parse the supplied value with
new URL()before launching or navigating the browser. - Allow only
https:and, where operationally necessary,http:URLs. - Reject URLs containing embedded usernames or passwords.
- Resolve hostnames before navigation and reject loopback, private, link-local, multicast, unspecified, and reserved IPv4 and IPv6 ranges.
- Revalidate every redirect destination rather than validating only the initial URL.
- Mitigate DNS rebinding by binding validation to the addresses actually used for browser requests.
- Disable
file:navigation by default. - If local HTML extraction is required, expose it through a separate path argument and:
- Require explicit user approval.
- Canonicalize the path with
realpath. - Restrict it to an approved directory.
- Reject symbolic-link escapes.
- Prevent local pages from loading arbitrary network or filesystem resources.
- Use Playwright request routing to block unnecessary subresources and requests to prohibited address ranges.
- Disable or block service workers for untrusted pages.
- Run the browser in an isolated container or network namespace with no access to cloud metadata, internal networks, or sensitive host files.
- Document that only trusted URLs may be processed when network-level isolation cannot be enforced.
- Parse the supplied value with
