Back to skill

Security audit

Cost Tracking for Models

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its cost-reporting purpose, but its CLI has a real shell-injection flaw and some Discord/error reporting can expose sensitive session-log details.

Review before installing. Use the shell scripts directly with trusted arguments rather than the Node CLI until the execSync command construction is fixed, and avoid Discord or cron reporting with --show-errors unless you are comfortable sharing raw model error messages from local OpenClaw session logs.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
cli.js:31
Finding

OS Command Injection Through Unsafely Constructed Shell Command

Content
View full analysis

Vulnerability Details

File Location: cli.js, lines 31–45
Vulnerability Type: OS command injection
Risk Level: High

Vulnerable Code

js
// Pass command line arguments to the script
const args = process.argv.slice(2);

try {
  // Set environment variables for the script
  const env = {
    ...process.env,
    LC_ALL: 'en_US.UTF-8', // Ensure English locale for number formatting
  };
  
  // Run script and capture output
  const output = execSync(`"${scriptPath}" ${args.map(arg => `"${arg}"`).join(' ')}`, {
    env,
    stdio: 'pipe',
    encoding: 'utf-8'
  });

Technical Analysis

The CLI incorporates every user-controlled command-line argument into a command string passed to Node.js execSync(). String-form execSync() invokes a shell, so shell syntax in the resulting command is interpreted rather than passed directly to cost_report.sh.

Wrapping each argument in double quotes is not sufficient escaping. An argument can contain a double quote that terminates the intended quoted context, followed by shell control operators and an arbitrary command. Shell substitutions such as $(...) also remain active inside double-quoted shell strings.

The shell script's own option validation does not mitigate the issue because the injected command is interpreted by the shell before cost_report.sh receives and validates its arguments.

Attack Path

  1. An attacker gains influence over arguments supplied to cli.js, such as through a wrapper, automation job, agent-generated command, or a command copied and executed by a user.

  2. The attacker provides an argument containing shell syntax. For example, the following demonstrates arbitrary command execution by creating a file:

    bash
    node cli.js --format '"; touch /tmp/openclaw-cli-injected; #'
    
  3. cli.js constructs a command resembling:

    bash
    "/path/to/scripts/cost_report.sh" "--format" ""; touch /tmp/openclaw-cli-injected; #"
    
  4. execSync() passes thi ...[truncated 983 chars]

Remediation
View remediation

Remediation Suggestions

Replace string-based execSync() with an API that passes arguments directly without invoking a shell, such as execFileSync():

js
const { execFileSync } = require('child_process');

const output = execFileSync(scriptPath, args, {
  env,
  stdio: 'pipe',
  encoding: 'utf-8',
  shell: false
});

Apply the following additional hardening measures:

  1. Validate arguments against the script's supported options before execution.
  2. Restrict --format to an explicit allowlist such as text, json, and discord.
  3. Reject missing values for options that require an argument.
  4. Do not attempt to solve the issue with custom shell escaping; avoid shell interpretation entirely.
  5. Add regression tests using arguments containing quotes, semicolons, command substitutions, backticks, newlines, and redirection operators.
  6. Prefer setting executable permissions during packaging or installation rather than invoking chmod on every CLI run.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (16)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

This second mismatch finding highlights additional undeclared behaviors, including reading local session logs and extracting model error details from session contents. Even if intended for reporting, accessing richer session content than advertised can expose more internal context than expected and creates a transparency and privacy problem.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

This second mismatch finding highlights additional undeclared behaviors, including reading local session logs and extracting model error details from session contents. Even if intended for reporting, accessing richer session content than advertised can expose more internal context than expected and creates a transparency and privacy problem.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The CLI constructs a shell command string and interpolates user-controlled arguments into execSync with only double-quote wrapping. In a shell, command substitution such as $(...) and backticks can still execute inside double quotes, so an attacker can inject arbitrary commands via CLI arguments, leading to command execution in the user's environment.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill declares shell/env capabilities but does not define any tool scope or permissions boundaries. In an agent ecosystem, this increases the chance that the skill can invoke shell access more broadly than users expect, especially since it operates on local files and external binaries like jq.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest describes a reporting skill for tracking OpenClaw usage costs and generating reports for messaging channels. In this file, the CLI invokes a shell command to change file permissions before execution, introducing host-level command execution and filesystem modification capabilities that are not obviously required by a cost-reporting function.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code unconditionally sets LC_ALL to en_US.UTF-8, which overrides the user's existing locale settings for every invocation. This is a natural-language/locale policy issue because it forces a specific language/locale without offering a choice or documenting a region-specific requirement.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The job description and agent message are written only in Chinese, which imposes a specific language/locale in the skill behavior. The file does not indicate that this is a China-specific deployment or offer any user opt-in or language selection, so it appears to violate the language/locale policy criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This weekly report job likewise uses Chinese-only natural-language instructions and descriptions. Because no locale scope, user choice, or regional justification is provided in the configuration, this is a repeat language policy issue.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script enumerates all agent session files under the user's OpenClaw directories, extracts usage metadata, and optionally includes raw error messages in the report. Error strings and model/session metadata can contain sensitive operational details, prompts, identifiers, or backend failure information, and the script emits them without any privacy warning, redaction, or confirmation step.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The script does more than generate a Discord cost report: it also scans local session logs and extracts Kimi-specific error details from raw JSONL files in the user's home directory. Error messages in session logs can contain sensitive prompts, identifiers, request fragments, or internal system details, so surfacing them in a reporting wrapper expands data exposure beyond the skill's stated purpose.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script directly reads raw agent session files from ~/.openclaw/agents/main/sessions, which likely contain broader conversational and operational data than cost metrics alone. That capability is not well aligned with the advertised function of cost tracking and increases the chance of unintended disclosure of local sensitive data through terminal output or downstream posting to Discord.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script reads potentially sensitive session data without any user-facing warning, consent flow, or disclosure, which is a transparency and privacy issue. In the context of a reporting skill that may feed Discord or other messaging channels, undisclosed access to local session logs makes accidental exfiltration more plausible and more harmful.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The installation/requirements section does not warn users that the skill reads local OpenClaw session logs, which may contain sensitive usage and model metadata. While this is primarily a transparency issue, it matters because local log access can reveal operational history and should be clearly disclosed before use.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

This markdown file contains user-facing natural-language documentation exclusively in Chinese, starting from the title and continuing throughout the file. Under the policy rule for language or locale constraints, forcing a single language without user opt-in can be a natural-language policy violation when no alternative language option or justification is provided.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The comments and behavior explicitly apply a specific regional convention for red/up and green/down in Discord output. This imposes a locale-specific presentation choice without offering the user a preference or documenting it as an optional regional mode.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script title/comments and runtime output strings are written in Chinese, which imposes a specific language on users without opt-in. Under the policy, forcing a locale or language without offering choice or clear justification is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
cli.js:25