Back to skill

Security audit

CLI AI Proxy

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it says, but it installs and runs an unpinned global npm package and includes unsafe root-level installation guidance that users should review carefully.

Install only if you are comfortable running a globally installed npm package that is not pinned to a reviewed version. Prefer a user-owned Node/npm setup, avoid the documented `curl | sudo bash` and `sudo npm install -g` paths, keep the proxy bound to 127.0.0.1, and review OpenClaw config changes before and after running the configure command.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T03 · Remote Payload Retrieval and Execution

Error
Location
references/troubleshooting.md:28
Finding

Unverified Remote Installation Script Executed with Root Privileges

Content
View full analysis

Vulnerability Details

File Location: references/troubleshooting.md:25-29
Vulnerability Type: Remote payload retrieval and execution
Risk Level: High

Vulnerable Code:

bash
Install Node.js (v18+):
- macOS: `brew install node`
- Linux: `curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - && sudo apt-get install -y nodejs`

Technical Analysis

The Linux installation instructions download content from a mutable external URL and pipe it directly into a Bash process running through sudo. No checksum, digital signature, immutable version, or manual inspection step is required before execution.

Because the effective script is retrieved at execution time, its behavior can differ from what was present when this project was audited. HTTPS authenticates the connection under normal conditions, but it does not protect against compromise of the remote publisher, distribution infrastructure, signing account, or a future unintended change to the hosted script.

The sudo -E bash invocation executes the downloaded script with root privileges while preserving parts of the caller's environment. This gives the remote payload substantially more authority than is necessary to provide troubleshooting documentation.

Attack Path

  1. An attacker compromises the NodeSource-hosted script, its publishing infrastructure, or another trusted component in the delivery chain.
  2. A user follows the documented Linux troubleshooting instructions.
  3. curl retrieves the attacker-controlled response.
  4. The shell pipeline passes the response directly to sudo -E bash without integrity verification or review.
  5. The payload executes as root and can modify any part of the operating system.
  6. The subsequent package installation does not undo any changes made by the remote payload.

Impact Assessment

Successful exploitation provides arbitrary command execution with root privileges. The paylo ...[truncated 454 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove the curl | sudo bash installation pattern.
  • Direct users to install Node.js through an operating-system package manager or another repository already configured through a trusted administrative process.
  • If an external bootstrap artifact is unavoidable, download it to a local file before execution.
  • Pin the artifact to an immutable version and publish an expected cryptographic checksum.
  • Verify the checksum and, where available, the publisher's digital signature before execution.
  • Require users to inspect the downloaded file separately rather than executing it as part of a network pipeline.
  • Avoid sudo -E because preserving the caller's environment across a privilege boundary can introduce additional risk.
  • Use the minimum privileges needed for each installation operation.

T08 · Insecure Dependencies

Error
Location
scripts/install.sh:10
Finding

Unpinned Global Installation of an Unaudited Runtime Package

Content
View full analysis

Vulnerability Details

File Location: scripts/install.sh:10-35
Vulnerability Type: Insecure third-party dependency installation
Risk Level: High

Vulnerable Code:

bash
PACKAGE_NAME="cli-ai-proxy"

echo "=== cli-ai-proxy installer ==="

# ─── Prerequisites ───

command -v node >/dev/null 2>&1 || { echo "ERROR: node not found. Install Node.js first."; exit 1; }
command -v npm  >/dev/null 2>&1 || { echo "ERROR: npm not found. Install Node.js first."; exit 1; }

HAS_GEMINI=false
HAS_CLAUDE=false
command -v gemini >/dev/null 2>&1 && HAS_GEMINI=true
command -v claude >/dev/null 2>&1 && HAS_CLAUDE=true

if [[ "$HAS_GEMINI" == false && "$HAS_CLAUDE" == false ]]; then
  echo "WARNING: Neither gemini nor claude CLI found in PATH."
  echo "  Install at least one before running the proxy:"
  echo "    Gemini CLI:  npm install -g @google/gemini-cli"
  echo "    Claude Code: npm install -g @anthropic-ai/claude-code"
  echo ""
fi

# ─── Install ───

echo "Installing $PACKAGE_NAME from npm..."
if npm install -g "$PACKAGE_NAME"; then
  :

Technical Analysis

The installer requests cli-ai-proxy without an exact version or integrity value. npm therefore resolves whichever release is current under that package name when the command runs. The package contains the substantive proxy implementation, but its source is not included in the audited project.

The local wrapper scripts subsequently trust and execute the globally installed cli-ai-proxy binary for startup, shutdown, health checks, status checks, and OpenClaw configuration. Consequently, the effective behavior of the Skill is controlled by code obtained dynamically from the npm registry rather than by the reviewed files.

A global installation can place a PATH-accessible executable in the user's global npm prefix. npm lifecycle scripts may also execute during installatio ...[truncated 2045 chars]

Remediation
View remediation

Remediation Suggestions

  • Pin cli-ai-proxy to a specific, reviewed version, for example cli-ai-proxy@X.Y.Z.
  • Record and verify the expected npm artifact integrity hash before installation.
  • Audit the pinned package contents and all transitive dependencies.
  • Re-audit and deliberately update the pin when adopting a new release.
  • Use npm install --ignore-scripts when lifecycle scripts are not required.
  • Prefer a project-local installation with a committed lockfile over a global installation.
  • Execute the package through a path tied to the pinned local dependency rather than resolving an arbitrary global binary from PATH.
  • Remove the recommendation to retry installation with sudo.
  • Apply npm provenance or registry-signature verification where supported.
  • Consider vendoring the reviewed implementation or distributing a signed, reproducible artifact so that the executed code matches the audited code.
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (10)

Chaining Abuse

High
Category
Tool Misuse
Confidence
89% confidence
Finding

Piping curl output directly into sudo creates a classic unsafe command chain where untrusted remote content is immediately executed with elevated privileges. In documentation, this normalizes a dangerous pattern that can cause full system compromise if the source is tampered with.

Content

Scanner excerpt · references/troubleshooting.md (reported line 28)May include surrounding context.

Install Node.js (v18+):

  • macOS: brew install node
  • Linux: curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - && sudo apt-get install -y nodejs

Build fails

bash

Chaining Abuse

High
Category
Tool Misuse
Confidence
89% confidence
Finding

Piping curl output directly into sudo creates a classic unsafe command chain where untrusted remote content is immediately executed with elevated privileges. In documentation, this normalizes a dangerous pattern that can cause full system compromise if the source is tampered with.

Content

Scanner excerpt · references/troubleshooting.md (reported line 28)May include surrounding context.

Install Node.js (v18+):

  • macOS: brew install node
  • Linux: curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - && sudo apt-get install -y nodejs

Build fails

bash

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/troubleshooting.md (reported line 34)May include surrounding context.

bash
# Clean and rebuild
cd <install-dir>
rm -rf dist/
npm run build

External Model or Provider Selection

High
Category
Excessive Agency
Confidence
90% confidence
Finding

Skill selects an external model or provider that may use a different account or billing plan than the operator expects. Undisclosed model switches can cause unexpected cost or quota consumption.

Content

Scanner excerpt · references/troubleshooting.md (reported line 101)May include surrounding context.

  1. Proxy logs for stderr output from the CLI
  2. Run the CLI manually to verify it works:
    bash
    echo "hello" | gemini --output-format stream-json --model gemini-2.5-flash
    
  3. CLI auth may have expired — re-authenticate

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
84% confidence
Finding

curl ... | sudo -E bash - pipes remote content directly into a root shell while preserving environment variables. If the remote script is compromised, intercepted, or the environment contains unsafe values, this can lead to immediate privileged code execution on the host.

Content

Scanner excerpt · references/troubleshooting.md (reported line 28)May include surrounding context.

Install Node.js (v18+):

  • macOS: brew install node
  • Linux: curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - && sudo apt-get install -y nodejs

Build fails

bash

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
84% confidence
Finding

curl ... | sudo -E bash - pipes remote content directly into a root shell while preserving environment variables. If the remote script is compromised, intercepted, or the environment contains unsafe values, this can lead to immediate privileged code execution on the host.

Content

Scanner excerpt · references/troubleshooting.md (reported line 28)May include surrounding context.

Install Node.js (v18+):

  • macOS: brew install node
  • Linux: curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - && sudo apt-get install -y nodejs

Build fails

bash

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The header comment says the script performs exactly one privileged action: npm install -g cli-ai-proxy. However, lines L69-L72 optionally run an additional command after installation. That means the inline documentation actively understates the script's behavior rather than merely omitting an implementation detail.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/install.sh (reported line 41)May include surrounding context.

sh
echo ""
  echo "Global install failed. If this is a permissions issue, try one of:"
  echo "  • Use a Node version manager (nvm, fnm, volta) so global installs go to \$HOME"
  echo "  • Re-run with sudo: sudo npm install -g $PACKAGE_NAME"
  exit 1
fi

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The cleanup command uses rm -f <install-dir>/tmp-images/img-*, which is destructive and presented without an explicit warning to verify the target path before execution. In troubleshooting docs this can lead to accidental deletion if users substitute the path incorrectly or run it from an unexpected context.

Content

No source excerpt is available for this finding.