Back to skill

Security audit

Cost Governor - Subagent Budget Control

Security checks for vulnerabilities and agentic risk

Overview

The skill is not overtly malicious, but it overstates its ability to enforce budget controls and keeps persistent cost logs that need careful review.

Review this skill before installing if you expect hard billing protection. Treat it as an advisory estimator/logger unless you add an enforced wrapper around subagent spawning, avoid storing sensitive task details in cost-tracking.md, and do not rely on the documented .env budget cap to stop spending.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • 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
  • 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 (3)

T02 · Agent Memory Poisoning

Warning
Location
lib/cost-tracker.js:87
Finding
Persistent Agent-Readable Log Injection Through Unsanitized Metadata<![CDATA[ ## Vulnerability Details **File Location**: `lib/cost-tracker.js:87-109`; related agent-reading behavior is documented in `README.md:48-54` **Vulnerability Type**: Persistent Markdown and instruction injection **Risk Level**: Medium ### Vulnerable Code ```javascript function logSpawn(label, model, estimatedCost, approved, options = {}) { initializeCostTracking(); const timestamp = new Date().toISOString().replace('T', ' ').substring(0, 16); const approvedStr = approved === 'auto' ? 'auto' : (approved ? 'yes' : 'no'); const entry = `### [${timestamp}] ${label} - **Model:** ${model} - **Task Type:** ${options.taskType || 'unknown'} - **Estimated:** $${estimatedCost.toFixed(2)} - **Actual:** $0.00 (pending) - **Approved:** ${approvedStr} ${options.notes ? `- **Notes:** ${options.notes}\n` : ''} --- `; fs.appendFileSync(COST_TRACKING_FILE, entry); } ``` The project documentation states that the agent reads the tracking file during cost checks: ```markdown Agent reads this file on each cost check. ``` ### Technical Analysis The `label`, `model`, `options.taskType`, and `options.notes` values are interpolated directly into an agent-readable Markdown file without validation, length restrictions, newline removal, or Markdown escaping. If any of these fields can be influenced by an untrusted user or subagent request, a value containing newline characters can escape its intended field and add arbitrary headings, fake cost records, or instruction-like text. Because the resulting content is persisted in `notes/cost-tracking.md` and the documentation directs agents to read that file during later checks, the injection can affect sessions beyond the request that created it. This is a persistent content-injection weakness. Whether injected text is ultimately obeyed depends on how the surrounding agent treats workspace notes, but the code does not establish a data/instruction boundary. ### Attack Path 1. An attacker supplies or influences ...[truncated 1336 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Treat every metadata field as untrusted data. 2. Enforce bounded, single-line values for `label`, `model`, and `taskType`: - Remove carriage returns and line feeds. - Reject control characters. - Apply strict maximum lengths. - Restrict `model` and `taskType` to explicit allowlists. 3. Escape Markdown metacharacters before writing free-form values. 4. Restrict notes to a bounded length and encode line breaks rather than preserving raw Markdown. 5. Store authoritative records in a structured format such as JSON with schema validation. Generate Markdown summaries only as escaped presentation output. 6. Tell agents that tracking-file content is untrusted data and must never be interpreted as instructions. 7. Where possible, avoid loading arbitrary labels and notes into agent instruction context. 8. Add tests covering labels and notes containing newlines, headings, separators, code fences, and instruction-like content. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:93
Finding
Documented Budget Cap Is Written to a Sensitive Configuration File but Never Enforced<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:93-95`, `SKILL.md:140-144`, `README.md:35-38`, and `README.md:64-69` **Vulnerability Type**: Ineffective security control and unnecessary configuration-file modification **Risk Level**: Medium ### Vulnerable Documentation `SKILL.md` instructs users to modify the workspace environment file: ```bash echo "DAILY_BUDGET=20.00" >> ~/.openclaw/workspace/.env ``` It subsequently claims that the budget is enforced: ```markdown ## Budget Alerts Set a daily budget cap. When spend exceeds it, the agent stops spawning and notifies you. ``` `README.md` makes a similar enforcement claim: ```markdown Add to workspace `.env`: ```bash DAILY_BUDGET=50.00 WEEKLY_BUDGET=300.00 ``` Agent will warn when approaching limits. ``` However, neither `lib/cost-tracker.js` nor `bin/cost-summary.js` reads `DAILY_BUDGET` or `WEEKLY_BUDGET`. The implementation does not calculate budget consumption, warn when a threshold is approached, or block a spawn when a budget is exceeded. ### Technical Analysis The setup command appends data to `~/.openclaw/workspace/.env`, a configuration file that may also contain API keys or other secrets. The command does not read or disclose existing credentials, but modification of this file is unnecessary for the current executable implementation because the budget value is never consumed. Using `>>` is also non-idempotent. Repeated setup adds duplicate definitions, leaving behavior dependent on how another environment loader resolves duplicate keys. The more significant issue is a fail-open control: users are told that a configured daily budget will stop spawning, while no executable enforcement exists. The Skill therefore presents an advisory configuration value as an active spending safeguard. ### Attack Path 1. A user follows the installation documentation and appends `DAILY_BUDGET` to the workspace `.env` file. 2. The user relies on the stated behavior that spending above the conf ...[truncated 1182 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Implement budget enforcement before documenting the setting as a hard cap. 2. Load `DAILY_BUDGET` and any other supported values through a defined configuration mechanism. 3. Strictly validate budget values as finite, non-negative decimal amounts with reasonable upper bounds. 4. Calculate current daily spending and include the proposed spawn estimate before authorizing execution. 5. Fail closed when: - Configuration is malformed. - Spend data cannot be read reliably. - The proposed operation would exceed the cap. 6. Ensure enforcement wraps the actual spawn operation rather than merely printing a warning. 7. Replace the append command with an idempotent configuration update that modifies a unique key atomically and preserves file permissions. 8. Prefer a dedicated non-secret Skill configuration file instead of modifying a shared `.env` file. 9. If enforcement will not be implemented, remove the `.env` command and clearly state that budgets are advisory only. 10. Add automated tests for exact-limit behavior, malformed values, duplicate settings, missing tracking files, and concurrent spawn requests. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
lib/cost-tracker.js:52
Finding
Approval Gate Is Advisory and Can Be Explicitly Bypassed<![CDATA[ ## Vulnerability Details **File Location**: `lib/cost-tracker.js:52-60`; bypass behavior is documented in `README.md:92-96` **Vulnerability Type**: Fail-open approval control **Risk Level**: Medium ### Vulnerable Code and Documentation The implementation only returns a Boolean: ```javascript /** * Check if approval is required * @param {number} estimatedCost - Estimated cost in USD * @returns {boolean} True if approval required */ function checkApprovalRequired(estimatedCost) { return estimatedCost > APPROVAL_THRESHOLD; } ``` The setup guide documents a direct bypass: ```markdown **Need to bypass gate?** - Say "proceed without cost check" (still logs) - Or reduce approval threshold in SKILL.md (not recommended) ``` ### Technical Analysis `checkApprovalRequired()` is a policy helper, not an enforcement boundary. It has no binding to the actual `sessions_spawn` operation, does not require an approval artifact, and does not reject execution when approval is absent. The project documentation describes approval for estimates above `$0.50` as a core rule, but also instructs users that the check can be bypassed with a phrase. No distinction is made between an authorized administrative override and an ordinary request. Because the enforcement depends entirely on the calling agent voluntarily invoking and honoring the helper, omitted integration, prompt manipulation, caller error, or the documented bypass can cause the control to fail open. ### Attack Path 1. A user or untrusted prompt requests an expensive subagent spawn. 2. The caller omits `checkApprovalRequired()`, ignores its return value, or follows the documented “proceed without cost check” bypass. 3. No code-level mechanism requires a matching explicit approval. 4. The underlying spawn operation proceeds. 5. The expensive operation incurs cost without the approval promised by the Skill's core rules. ### Impact Assessment This flaw does not grant operating-system privileges or permit ...[truncated 599 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Place enforcement in a mandatory wrapper around the actual subagent-spawn operation. 2. For estimates above the threshold, require an explicit approval artifact tied to: - The requesting user. - The exact task. - The selected model. - The approved estimate or maximum cost. - A short expiration time. 3. Reject expensive spawns when approval is missing, stale, malformed, or associated with different parameters. 4. Prevent callers from directly reaching the underlying spawn operation without passing through the policy wrapper. 5. Remove the phrase-based bypass from the documentation. 6. If overrides are operationally necessary, require a separately authorized administrative mechanism and log the identity, reason, parameters, and timestamp. 7. Validate `estimatedCost` with `Number.isFinite()` and reject negative or invalid values before applying the threshold. 8. Add tests proving that callers cannot spawn above the threshold without valid approval. 9. Clearly describe the Skill as advisory if the platform cannot technically enforce the gate. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (14)

Credential Access

High
Category
Privilege Escalation
Content
2. **Set daily budget (optional):**
```bash
echo "DAILY_BUDGET=20.00" >> ~/.openclaw/workspace/.env
```

3. **Test it:**
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
2. **Set daily budget (optional):**
```bash
echo "DAILY_BUDGET=20.00" >> ~/.openclaw/workspace/.env
```

3. **Test it:**
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The declared purpose promises preventive controls before `sessions_spawn`, but the skill content mainly provides guidance, logging, and retrospective reporting rather than an enforceable gate. That mismatch is dangerous because users may rely on it as a hard cost-control mechanism when it does not actually prevent expensive actions, and it also introduces undeclared file reads/writes to tracking data.

Ae1

High
Category
analysis-evasion
Content
- `SKILL.md` — This file (agent instructions)
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- `bin/cost-summary.js` — CLI: daily/monthly spend summary
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Session Persistence

Medium
Category
Rogue Agent
Content
## First-Time Setup

1. **Create tracking file:**
```bash
mkdir -p ~/.openclaw/workspace/notes
cat > ~/.openclaw/workspace/notes/cost-tracking.md << 'EOF'
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.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The README says the skill activates automatically when the user asks to spawn a subagent or requests a cost estimate, but it does not define narrower trigger phrases, scope limits, or exclusions. These are common intents that could overlap with many normal interactions, making invocation boundaries unclear.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The documented bypass phrase 'proceed without cost check' is generic and unconstrained, which creates a weak override path for a safety-control skill. If an agent treats that phrase as sufficient authority, prompt injection, accidental phrasing, or indirect user content could disable the approval gate and undermine the budget-protection purpose of the skill.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
## Examples

### Example 1: Cheap Task (Auto-Approved)

```
You: "Quick lookup: What's the capital of France?"
Confidence
85% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
```
You: "Quick lookup: What's the capital of France?"
Agent: [estimates $0.05, auto-approves, spawns on Haiku]
```

### Example 2: Expensive Task (Gated)
Confidence
85% confidence
Finding
The example says the agent 'auto-approves' and 'spawns on Haiku,' which is an autonomous action affecting resource consumption without an explicit approval step. Even if the spend is small, repeated low-cost automatic spawns can accumulate cost and normalize bypassing user confirmation for actions that have billing impact.

Lp3

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding
The skill instructs use of environment-backed configuration via `.env` and implies stateful behavior, but the manifest does not declare any tool scope or permissions for environment/file access. This creates a transparency and least-privilege problem: operators cannot accurately assess what resources the skill expects to touch, increasing the chance of unauthorized reads or writes during execution.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill requires logging all spawns to a workspace tracking file without clearly obtaining user consent for persistence of task details. Silent recording of prompts, task names, or model usage can expose sensitive operational or business information to anyone with access to the workspace notes.

Session Persistence

Medium
Category
Rogue Agent
Content
## Setup

1. Create cost tracking file:
```bash
mkdir -p ~/.openclaw/workspace/notes
touch ~/.openclaw/workspace/notes/cost-tracking.md
Confidence
80% confidence
Finding
The skill explicitly creates persistent workspace state under `notes/cost-tracking.md`, causing task metadata to accumulate across sessions. Persistent local records are not inherently malicious, but they can become a privacy and information disclosure risk if they store sensitive task names, budgets, or operational history without retention controls.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The approval flow says low-cost operations may proceed and be logged silently, which normalizes unannounced file writes for routine activity. Even if the cost is low, the task content may still be sensitive, so hidden persistence increases privacy and data-handling risk.

Static analysis

Detected: suspicious.prompt_injection_instructions

Prompt-injection style instruction pattern detected.

Warn
Code
suspicious.prompt_injection_instructions
Location
SKILL.md:147