| Título | CosmicStack Labs Mercury Agent (@cosmicstack/mercury-agent) <= 1.2.0 Incorrect Privilege Assignment (CWE-266) / Exposure of Sensitive Information (CWE-200) |
|---|
| Descrição | # Technical Details
A shell approval bypass leading to environment variable disclosure exists in the `checkShellCommand` method in `src/capabilities/permissions.ts` of Mercury Agent.
Mercury classifies `echo *` as a safe read-only shell command and auto-approves it, but `run_command` later executes the exact same command string through a real system shell (`spawn(command, [], { shell: true })`). Because the permission decision is made on the superficial command form before shell expansion, an attacker can use `echo $VAR` to trigger shell-side environment variable expansion and disclose sensitive process environment values (API keys, GitHub tokens, deployment credentials) without triggering the intended approval prompt. The direct equivalent `printenv VAR` is correctly blocked with a permission prompt, while `echo $VAR` is silently approved and returns the secret value.
# Vulnerable Code
File: src/capabilities/permissions.ts
Method: checkShellCommand() / SAFE_READ_PATTERNS
Why: `'echo *'` is whitelisted in SAFE_READ_PATTERNS and any command whose segments all match a safe-read pattern is auto-approved (`{ allowed: true, needsApproval: false }`) without argument-level semantic validation, so `echo $VAR` is treated as safe.
File: src/capabilities/shell/run-command.ts
Method: run_command execution sink
Why: `const child = spawn(command, [], { cwd, shell: true, stdio: ['pipe','pipe','pipe'] })` executes the already-approved string through the shell, allowing `$VAR` expansion after the permission decision was made.
# Reproduction
1. Run a Mercury instance (Web or CLI) with a secret environment variable set, e.g. `MERCURY_GHSA_JCCR_RRW2_VC8H_SECRET=ghsa-jccr-rrw2-vc8h-vuln-canary`.
2. Control: prompt `printenv MERCURY_GHSA_JCCR_RRW2_VC8H_SECRET` — observe a permission prompt and denial.
3. Control: prompt `echo MERCURY_GHSA_JCCR_RRW2_VC8H_SECRET` — auto-approved, returns only the literal variable name.
4. Exploit: prompt `echo $MERCURY_GHSA_JCCR_RRW2_VC8H_SECRET` — no approval prompt, shell expands the variable and returns the real secret value.
5. Reachable via normal Web channel: `POST /api/chat/send` in `src/web/api/chat.ts` -> `WebChannel.emitMessageInThread()` -> model-selected `run_command` -> `PermissionManager.checkShellCommand()` -> shell execution sink.
# Impact
- Authorization / approval bypass leading to sensitive information disclosure.
- Exposure of LLM provider API keys, GitHub tokens, deployment credentials, third-party integration secrets, and other process-level sensitive configuration.
- Breaks the security promise that dangerous shell actions are surfaced for user confirmation.
- Severity: High, CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N. |
|---|
| Fonte | ⚠️ https://github.com/cosmicstack-labs/mercury-agent/issues/80 |
|---|
| Utilizador | Eric-a (UID 96353) |
|---|
| Submissão | 11/08/2026 15h11 (há 1 mês) |
|---|
| Moderação | 13/09/2026 18h30 (1 month later) |
|---|
| Estado | Aceite |
|---|
| Entrada VulDB | 403314 [cosmicstack-labs mercury-agent até 1.2.0 Shell Command Permission permissions.ts checkShellCommand Elevação de Privilégios] |
|---|
| Pontos | 20 |
|---|