T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/extract-wc-uri.js:82
- Finding
- Unrestricted Browser Target Enables Blind Server-Side Request Forgery<![CDATA[ ## Vulnerability Details **File Location**: `scripts/extract-wc-uri.js`, lines 16 and 33-43; user-controlled input originates at lines 82-89 **Vulnerability Type**: Unrestricted URL navigation / blind server-side request forgery **Risk Level**: Medium ### Vulnerable Code ```javascript async function extractWalletConnectURI(url, timeout) { // Note: Running without --no-sandbox for better security isolation // If you encounter permission issues on Linux, consider running with proper user permissions // rather than disabling sandbox const browser = await puppeteer.launch({ headless: 'new', // Security: Sandbox enabled by default (removed --no-sandbox) }); try { const page = await browser.newPage(); // Navigate to login page console.error('📧 Navigating to EtherMail...'); await page.goto(url, { waitUntil: 'networkidle2', timeout }); // Wait for page to stabilize await page.waitForTimeout(2000); // Click the wallet login button console.error('🔑 Looking for wallet login button...'); const walletButton = await page.$('[data-testid="wallet-login"], button:has-text("wallet"), [class*="wallet"]'); if (walletButton) { await walletButton.click(); await page.waitForTimeout(3000); } ``` The navigation target is populated directly from command-line input: ```javascript const args = process.argv.slice(2); let url = DEFAULT_URL; let timeout = DEFAULT_TIMEOUT; for (let i = 0; i < args.length; i++) { if (args[i] === '--url' && args[i + 1]) { url = args[++i]; } else if (args[i] === '--timeout' && args[i + 1]) { timeout = parseInt(args[++i], 10); } ``` ### Technical Analysis The `--url` argument is passed directly to `page.goto()` without validating its protocol, hostname, resolved IP address, or redirect destination. Although the Skill is specifically intended to access the EtherMail login page, the implementation permits Chromium to navigate to arbitrary at ...[truncated 2124 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove the `--url` option if only the EtherMail login page is required. 2. If configurability is necessary, parse the input with `new URL()` and allow only: - The `https:` protocol. - An explicit allowlist of trusted EtherMail hostnames. - Expected login paths. 3. Validate every redirect destination rather than validating only the initial URL. 4. Resolve destination hostnames and reject loopback, link-local, private, multicast, and reserved IP ranges for both IPv4 and IPv6. 5. Enable Puppeteer request interception and abort requests to disallowed origins or resolved addresses. 6. Replace broad wallet-related element matching with a precise, verified EtherMail login selector. 7. Run the browser in a network-isolated environment that cannot reach internal control-plane or metadata services. 8. Add automated tests covering direct internal URLs, alternative schemes, DNS rebinding, IPv6 loopback addresses, and public-to-private redirects. ]]>
