Skip to content

ADV-SHELL: API Key Interpolated Without Escaping in telegram-bridge.js #573

@ReterAI

Description

@ReterAI

Description

ADV-SHELL: API Key Interpolated Without Escaping in telegram-bridge.js

Field Value
Severity Low
CWE N/A (defense-in-depth)
File scripts/telegram-bridge.js
Line 102
Function runAgentInSandbox(message, sessionId)
Status Active

Description

The NVIDIA_API_KEY environment variable is interpolated into a single-quoted shell command string without escaping. The resulting command is sent over SSH to execute on a remote sandbox host. If the API key contained a single quote character, it would break out of the shell quoting and allow arbitrary command execution on the remote host.

Vulnerable Code

// scripts/telegram-bridge.js:93-107

function runAgentInSandbox(message, sessionId) {
  return new Promise((resolve) => {
    const sshConfig = execSync(`"${OPENSHELL}" sandbox ssh-config "${SANDBOX}"`, { encoding: "utf-8" });

    const confPath = `/tmp/nemoclaw-tg-ssh-${sessionId}.conf`;
    require("fs").writeFileSync(confPath, sshConfig);

    const escaped = message.replace(/'/g, "'\\''");  // ← message IS escaped (correct)
    const cmd = `export NVIDIA_API_KEY='${API_KEY}' && nemoclaw-start openclaw agent --agent main --local -m '${escaped}' --session-id 'tg-${sessionId}'`;
    //                                  ^^^^^^^^^ NOT escaped

    const proc = spawn("ssh", ["-T", "-F", confPath, `openshell-${SANDBOX}`, cmd], {
      timeout: 120000,
      stdio: ["ignore", "pipe", "pipe"],
    });

API_KEY is sourced from process.env.NVIDIA_API_KEY at line 30.

Why This Is Low Severity

  1. Operator-controlled inputAPI_KEY comes from an environment variable set by the person deploying the bridge, not from Telegram users or any external source.
  2. Key format precludes exploitation — NVIDIA API keys use the format nvapi-... with alphanumeric characters and hyphens. A single quote cannot appear in a valid key.
  3. User input IS properly escaped — The message parameter (from Telegram chat) is correctly escaped using the standard POSIX single-quote escaping pattern (replace(/'/g, "'\\''")) before interpolation.
  4. sessionId is safe — It is the Telegram chatId, a numeric value.

Recommended Fix

Apply the same POSIX single-quote escaping already used for message:

const escaped = message.replace(/'/g, "'\\''");
const escapedKey = API_KEY.replace(/'/g, "'\\''");
const cmd = `export NVIDIA_API_KEY='${escapedKey}' && nemoclaw-start openclaw agent --agent main --local -m '${escaped}' --session-id 'tg-${sessionId}'`;

This is a one-line defense-in-depth improvement with zero risk of regression.

Reproduction Steps

As above

Environment

As above

Debug Output

As above

Logs

As above

Checklist

  • I confirmed this bug is reproducible
  • I searched existing issues and this is not a duplicate

Metadata

Metadata

Assignees

No one assigned

    Labels

    Integration: TelegramUse this label to identify Telegram bot integration issues with NemoClaw.bugSomething isn't workingpriority: mediumIssue that should be addressed in upcoming releasessecuritySomething isn't secure

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions