From 0a65fb20f6fc29d61611571065fcdd9eacaa54d1 Mon Sep 17 00:00:00 2001 From: seonghobae <8172694+seonghobae@users.noreply.github.com> Date: Wed, 10 Jun 2026 13:58:03 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=92=20Sentinel:=20[HIGH]=20Fix=20Comma?= =?UTF-8?q?nd=20Injection=20via=20Unsanitized=20URL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaced the unsafe use of `child_process.exec()` for opening URLs in `packages/cli/src/lib/auth-flow.ts` with the dedicated `open` package. 🎯 What: The vulnerability fixed is a Command Injection vulnerability in `openBrowser` function. ⚠️ Risk: Passing unsanitized URLs to `exec` could allow command injection if the URL contained malicious shell characters, leading to arbitrary code execution. 🛡️ Solution: Used the `open` library, which safely uses OS-specific methods to open URLs without passing strings directly to a shell. --- .jules/sentinel.md | 4 ++++ packages/cli/package.json | 1 + packages/cli/src/lib/auth-flow.ts | 8 ++------ pnpm-lock.yaml | 3 +++ 4 files changed, 10 insertions(+), 6 deletions(-) create mode 100644 .jules/sentinel.md diff --git a/.jules/sentinel.md b/.jules/sentinel.md new file mode 100644 index 0000000..c7365d9 --- /dev/null +++ b/.jules/sentinel.md @@ -0,0 +1,4 @@ +## 2024-05-24 - Command Injection via Unsanitized URL + **Vulnerability:** Unsanitized URL was passed directly to the `child_process.exec()` function in `packages/cli/src/lib/auth-flow.ts`, opening the application up to potential command injection. + **Learning:** Never pass unsanitized user inputs to functions that execute shell commands like `exec`. Using `child_process.execFile` or dedicated packages like `open` is safer. + **Prevention:** Use secure alternatives for launching files or URLs. In this case, use the `open` library, which safely opens files or URLs using the operating system's default applications. diff --git a/packages/cli/package.json b/packages/cli/package.json index 5b33992..b330262 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -23,6 +23,7 @@ "@inquirer/prompts": "^7", "chalk": "^5", "commander": "^12", + "open": "^11.0.0", "ora": "^8" }, "devDependencies": { diff --git a/packages/cli/src/lib/auth-flow.ts b/packages/cli/src/lib/auth-flow.ts index 6c9271b..c4651e0 100644 --- a/packages/cli/src/lib/auth-flow.ts +++ b/packages/cli/src/lib/auth-flow.ts @@ -1,15 +1,11 @@ -import { exec } from 'child_process' +import open from 'open' import chalk from 'chalk' import ora from 'ora' import type { User, LoginResponse } from '@argos/shared' import { apiRequest } from './api-client.js' function openBrowser(url: string): void { - const cmd = - process.platform === 'darwin' ? 'open' : - process.platform === 'win32' ? 'start ""' : - 'xdg-open' - exec(`${cmd} "${url}"`) + open(url).catch(() => {}) } /** diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f6ff063..dcddd8e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -32,6 +32,9 @@ importers: commander: specifier: ^12 version: 12.1.0 + open: + specifier: ^11.0.0 + version: 11.0.0 ora: specifier: ^8 version: 8.2.0