Back to skill

Security audit

Token Budget Monitor

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a coherent local token-usage tracker, but its documented integration shows an unsafe shell command pattern that could execute unintended commands if copied into cron-job code with attacker-influenced values.

Review the integration example before installing. Do not copy the exec() string-concatenation pattern into cron jobs; use execFile() or spawn() with argument arrays and validate job names, token counts, and model identifiers. Also consider whether persistent local usage logs under ~/.openclaw/workspace/outputs are acceptable for your workflow.

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
SKILL.md:36
Finding

Shell Command Injection in Documented Integration

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 36-41
Vulnerability Type: Shell command injection through unsafe argument concatenation
Risk Level: High

Vulnerable Code

javascript
// After LLM call completes
const usage = result.usage;
exec('node /path/to/track-usage.js track <job-name> ' + 
  usage.input_tokens + ' ' + usage.output_tokens + ' ' + model);

Technical Analysis

The documented integration constructs a shell command by concatenating runtime values and passes the resulting string to exec(). Because exec() invokes a shell, shell metacharacters contained in model, token values, or a dynamically substituted job name can alter the intended command.

No quoting, allowlist validation, or shell escaping is applied. If an upstream API response, configuration source, plugin, or other attacker-influenced input controls one of these values, payloads containing separators or command substitutions could cause an additional operating-system command to execute.

The implementation in track-usage.js does not itself launch subprocesses; the vulnerability exists in the integration pattern explicitly recommended by the skill documentation.

Attack Path

  1. A user integrates the skill using the documented exec() example.
  2. An attacker gains influence over model or another value concatenated into the command, such as through a compromised or attacker-controlled upstream response.
  3. The attacker supplies a value containing shell syntax that terminates or extends the intended command.
  4. The application concatenates that value into the command string without validation or escaping.
  5. exec() submits the complete string to the system shell.
  6. The shell interprets the injected syntax and executes attacker-selected commands with the privileges of the OpenClaw or cron-job process.

Impact Assessment

Successful exploitation provides arbitrary command execution under the account running the integrating proce ...[truncated 460 chars]

Remediation
View remediation

Remediation Suggestions

Avoid invoking a shell. Use execFile() or spawn() with an argument array so runtime values are passed as literal arguments:

javascript
const { execFile } = require('child_process');

execFile('node', [
  '/path/to/track-usage.js',
  'track',
  jobName,
  String(usage.input_tokens),
  String(usage.output_tokens),
  model
], (error, stdout, stderr) => {
  if (error) {
    console.error('Usage tracking failed:', error);
    return;
  }
  console.log(stdout);
});

Apply defense-in-depth validation before execution:

  • Require token counts to be finite, non-negative integers within reasonable upper bounds.
  • Restrict job names to a documented safe format, such as /^[A-Za-z0-9._-]{1,100}$/.
  • Validate model identifiers against an allowlist or a narrowly defined format.
  • Reject control characters and unexpected input rather than attempting ad hoc shell escaping.
  • Use an absolute, trusted Node.js executable path when the runtime environment permits.
  • Update SKILL.md so users are not instructed to concatenate untrusted values into shell commands.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (4)

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · README.md (reported line 31)May include surrounding context.

Configuration

Create config.json in skill directory:

json
{

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The README explicitly documents writing token-usage data to a persistent file under the user's home directory, but does not warn that operational metadata such as job names, execution cadence, and token volumes may be retained long-term and exposed to other local processes or backups. While the example does not show secrets, persistent telemetry can still reveal sensitive workflow details and should be treated as potentially sensitive data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The code creates a directory and writes usage information, including job names, model identifiers, and token counts, to ~/.openclaw/workspace/outputs/token-usage.json. Although the track command logs that tokens were tracked after the fact, there is no prior disclosure or explicit warning that this data will be persisted on disk.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.