T09 · Insecure Skill Coding Practices
- Location
src/lib/open.ts:5- Finding
Shell Command Injection Through a Server-Provided Authentication URL
- Content
View full analysis
{ const { data } = await apiClient().get<{ data: AuthUrlResponse }>( "/api/auth/lite/auth-url" ); return data.data; } ``` ```ts // src/lib/auth.ts:169-172 output.log(` Opening browser...`); openUrl(authUrl); output.log(` Login link: ${authUrl}\n`); output.log(" Complete login in your browser, then press ENTER.\n"); ``` ```ts // src/lib/open.ts:5-20 import { exec } from "child_process"; export function openUrl(url: string): void { const platform = process.platform; let cmd: string; if (platform === "darwin") { cmd = `open "${url}"`; } else if (platform === "win32") { cmd = `start "" "${url}"`; } else { // Linux / others cmd = `xdg-open "${url}"`; } exec(cmd, (err) => { if (err) { // Silently fail — the URL is always printed as fallback } }); } ``` ### Technical Analysis The authentication URL is supplied by the remote ACP service and passed directly to `openUrl`. That function interpolates the URL into a shell command and invokes it using `child_process.exec`. Placing attacker-controlled data inside double quotes does not make shell execution safe. On Unix-like platforms, constructs such as command substitution can still be evaluated inside double quotes. Platform-specific shell metacharacters can create equivalent risks on Windows. There is no validation that the returned value: - Uses HTTPS. - Belongs to an expected Virtuals authentication host. - Is free of shell metacharacters. - Represents an ordinary HTTP or HTTPS URL. This makes the remote authentication response part of a local command-execution boundary. ### Attack Path 1. An attacker gains cont ...[truncated 971 chars]- Remediation
View remediation
