-
Notifications
You must be signed in to change notification settings - Fork 2.2k
CRITICAL: NVIDIA API Key Exposed in Process Arguments and Terminal Output #579
Description
Description
CRITICAL: NVIDIA API Key Exposed in Process Arguments and Terminal Output
| Field | Value |
|---|---|
| Severity | Critical |
| CWE | CWE-214 (Invocation of Process Using Visible Sensitive Information) |
| Files | 6 files, 8+ locations |
| Status | Active |
Description
The NVIDIA_API_KEY is passed as a command-line argument to child processes in multiple scripts and JavaScript files. On Linux/macOS, command-line arguments are visible to any local user via ps aux or /proc/<pid>/cmdline. In one case, the raw key is also echoed to the terminal in cleartext.
This affects the production CLI tool, the setup scripts, the onboarding flow, and the E2E test harness.
Affected Locations
1. Key echoed to terminal in cleartext (WORST)
File: scripts/walkthrough.sh:72
echo " export NVIDIA_API_KEY=$NVIDIA_API_KEY"When tmux is not available, the script prints the full API key value to stdout as part of suggested commands. This value will appear in:
- Terminal scrollback buffers
- Terminal session recordings
- CI/CD logs if run in automation
- Screen sharing / screenshots
2. Key embedded in tmux command string
File: scripts/walkthrough.sh:88
tmux split-window -h -t "$SESSION" \
"openshell sandbox connect nemoclaw -- bash -c 'export NVIDIA_API_KEY=$NVIDIA_API_KEY && nemoclaw-start openclaw agent --agent main --local --session-id live'"The API key is embedded in the tmux command, visible via:
tmux list-windows -F '#{pane_start_command}'ps auxduring command startup
3. Key as openshell credential argument
File: scripts/setup.sh:122-126
upsert_provider \
"nvidia-nim" \
"openai" \
"NVIDIA_API_KEY=$NVIDIA_API_KEY" \ # ← passed as CLI argument
"OPENAI_BASE_URL=https://integrate.api.nvidia.com/v1"The upsert_provider function passes credentials as arguments to openshell provider create --credential, making them visible in the process table.
4. Key as sandbox environment argument
File: scripts/setup.sh:182-184
openshell sandbox create --from "$BUILD_CTX/Dockerfile" --name "$SANDBOX_NAME" \
--provider nvidia-nim \
-- env NVIDIA_API_KEY="$NVIDIA_API_KEY" > "$CREATE_LOG" 2>&1The key is passed as a CLI argument to openshell sandbox create. Note: the script is aware of this risk — line 189 filters the log output to avoid displaying it:
# Show progress lines (filter apt noise and env var dumps that contain NVIDIA_API_KEY)5. Key in sudo command string
File: bin/nemoclaw.js:91
run(`sudo -E NVIDIA_API_KEY="${process.env.NVIDIA_API_KEY}" bash "${SCRIPTS}/setup-spark.sh"`);The key is visible in the sudo command line. Both the parent process and the child bash process expose the key in /proc/*/cmdline.
6. Key as openshell provider credential (JavaScript)
File: bin/lib/onboard.js:729-734
run(
`openshell provider create --name nvidia-nim --type openai ` +
`--credential "NVIDIA_API_KEY=${process.env.NVIDIA_API_KEY}" ` +
`--config "OPENAI_BASE_URL=https://integrate.api.nvidia.com/v1" 2>&1 || true`,
{ ignoreError: true }
);Same issue as setup.sh — credential passed as CLI argument to openshell.
7. Key as sandbox env argument (JavaScript)
File: bin/lib/onboard.js:468-470
if (process.env.NVIDIA_API_KEY) {
envArgs.push(`NVIDIA_API_KEY=${process.env.NVIDIA_API_KEY}`);
}These envArgs are later passed as -- env KEY=VALUE CLI arguments to openshell sandbox create.
8. Key in curl Authorization header (test)
File: test/e2e/test-full-e2e.sh:229
-H "Authorization: Bearer $NVIDIA_API_KEY" \The API key appears as a curl command-line argument, visible in the process table during the HTTP request.
9. Key in SSH command string (telegram bridge)
File: scripts/telegram-bridge.js:102
const cmd = `export NVIDIA_API_KEY='${API_KEY}' && nemoclaw-start openclaw agent --agent main --local -m '${escaped}' --session-id 'tg-${sessionId}'`;The key is embedded in the SSH command string passed to spawn("ssh", [..., cmd]), visible in the process table. See separate report adv_shell_telegram_bridge.md for full analysis.
Impact
Any user on the same machine can harvest API keys by monitoring process arguments:
# Attacker's one-liner to harvest API keys from process arguments:
while true; do
ps aux | grep -oP 'NVIDIA_API_KEY=\K[^ "]+' >> /tmp/harvested_keys.txt
sleep 0.1
doneThis is especially concerning in:
- Shared development machines — multiple developers on the same box
- CI/CD runners — shared runners process multiple tenants
- Brev/cloud VMs — the
deploy()function sends credentials to cloud instances
Recommended Fixes
For shell scripts (walkthrough.sh, setup.sh)
Echo fix (walkthrough.sh:72): Don't expand the variable — reference it instead:
# Before (leaks the key):
echo " export NVIDIA_API_KEY=$NVIDIA_API_KEY"
# After (safe — tells user to use their existing env var):
echo " export NVIDIA_API_KEY=\$NVIDIA_API_KEY"Tmux fix (walkthrough.sh:88): Use tmux send-keys to type the export into the pane:
tmux split-window -h -t "$SESSION" "openshell sandbox connect nemoclaw"
tmux send-keys -t "$SESSION".1 "export NVIDIA_API_KEY=$NVIDIA_API_KEY && nemoclaw-start openclaw agent --agent main --local --session-id live" Enteropenshell credential fix (setup.sh, onboard.js): Check if openshell provider create supports --credential-stdin or --credential-file. If not, pass via environment variable:
# Before:
openshell provider create --credential "NVIDIA_API_KEY=$NVIDIA_API_KEY"
# After (if openshell supports env passthrough):
NVIDIA_API_KEY="$NVIDIA_API_KEY" openshell provider create --credential-env NVIDIA_API_KEYFor JavaScript (nemoclaw.js, onboard.js)
Use the env option of spawnSync/execSync:
// Before (key in CLI args):
run(`sudo -E NVIDIA_API_KEY="${process.env.NVIDIA_API_KEY}" bash "${SCRIPTS}/setup-spark.sh"`);
// After (key passed via process environment, not visible in ps):
run(`sudo -E bash "${SCRIPTS}/setup-spark.sh"`, {
env: { ...process.env, NVIDIA_API_KEY: process.env.NVIDIA_API_KEY }
});For curl (test-full-e2e.sh)
Use a netrc file or config file:
# Before:
curl -H "Authorization: Bearer $NVIDIA_API_KEY" ...
# After:
curl --config <(echo "-H \"Authorization: Bearer $NVIDIA_API_KEY\"") ...Or use -H @- with stdin if supported by the curl version.
Risk Assessment
- Impact: Credential theft by any local user on shared systems
- Exploitability: Trivial — single
ps aux | grepcommand - Blast radius: NVIDIA API key provides access to inference endpoints at
integrate.api.nvidia.comandinference-api.nvidia.com, potentially incurring costs on the victim's account - Mitigating factors: On single-user developer machines, the only user who can read process args is the same user who owns the key. The risk is primarily on shared/CI systems.
Reproduction Steps
Environment
Debug Output
-Logs
-Checklist
- I confirmed this bug is reproducible
- I searched existing issues and this is not a duplicate