T09 · Insecure Skill Coding Practices
- Location
index.js:3- Finding
Unrestricted URL Navigation in an Unsandboxed Chromium Process
- Content
View full analysis
{ const browser = await puppeteer.launch({ headless: "new", args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'], defaultViewport: { width: 1280, height: 800 } }); try { const page = await browser.newPage(); // Set a standard user agent to avoid immediate blocks await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'); // Navigate to the tweet URL console.log("Navigating to:", url); await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 30000 }); ``` ### Technical Analysis The URL is read directly from `process.argv[2]` and passed to `page.goto()` without validation of its scheme, hostname, port, destination address, or redirect chain. Although `SKILL.md` states that callers should provide an `https://x.com/...` permalink, this requirement is not enforced by the implementation. A caller can therefore direct the browser to an arbitrary HTTP or HTTPS destination, including an attacker-controlled website, loopback service, or private-network endpoint reachable from the skill's execution environment. This creates an SSRF-like browser request primitive. Loading an attacker-controlled page also permits that page's JavaScript and subresources to execute inside Chromium. The associated browser is launched with both `--no-sandbox` and `--disable-setuid-sandbox`, disabling important Chromium process-isolation controls. If malicious page content exploits a browser vulnerability, the absence of the sandbox may substantially increase the potential impact. The ...[truncated 1965 chars]- Remediation
View remediation
