T09 · Insecure Skill Coding Practices
- Location
api/browser/open-url.js:18- Finding
Shell Command Injection in URL-Opening Utility
- Content
View full analysis
hostname === host || hostname.endsWith('.' + host)) } catch { return false } } async function openUrl(url) { if (!url) throw new Error('URL is required') if (!isAllowedUrl(url)) throw new Error(`URL not allowed: ${url}`) if (process.platform === 'darwin') { await execAsync(`open "${url}"`) } else if (process.platform === 'win32') { await execAsync(`start "" "${url}"`) } else { await execAsync(`xdg-open "${url}"`) } } ``` ### Technical Analysis The URL validator checks only the parsed protocol and hostname. It does not prevent shell metacharacters or command substitutions in the URL path, query, or fragment. The validated string is subsequently interpolated into a command passed to `child_process.exec`. The `exec` API invokes a system shell. Wrapping the URL in double quotes does not prevent all shell expansion; on Unix-like systems, constructs such as `$(command)` and backtick command substitutions remain active inside double-quoted strings. Although the normal `processQuery` flow currently generates URLs from static hospital data, `openUrl` is exported and the file also exposes a command-line interface that directly consumes `process.argv[2]`. Exploitation therefore requires an attacker to control an argument passed to the exported function or CLI. ### Attack Path 1. An attacker gains control over a URL supplied to the exported `openUrl` function or the command-line entry point. 2. The attacker supplies an HTTPS URL whose hostname passes the allowlist but whose path contains shell syntax, for example: ```text https://i.beautsgo.com/$(id) ``` 3. `new URL()` reports the pe ...[truncated 849 chars]- Remediation
View remediation
