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: telegramTelegram integration or channel behaviorsecurityPotential vulnerability, unsafe behavior, or access risk

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions