Back to skill

Security audit

Cost Monitor

Security checks for vulnerabilities and agentic risk

Overview

The skill’s cost-tracking purpose is mostly coherent, but it includes an unsafe balance-setting helper and under-disclosed credential/API use that users should review before installing.

Review before installing. The main cost display behavior is understandable, but do not use the set-balance helper until its argument handling is fixed. Only run DeepSeek calibration if you are comfortable with the skill reading your local OpenClaw DeepSeek credential and contacting DeepSeek's balance API. Back up balance.json if you rely on its values.

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
scripts/set-balance.sh:13
Finding

Arbitrary Python Code Execution Through an Unescaped Balance Argument

Content
View full analysis

Vulnerability Details

File Location: scripts/set-balance.sh, lines 13–20
Vulnerability Type: Command injection through dynamically constructed Python source
Risk Level: High

Vulnerable Code

bash
python3 -c "
import json
with open('$BALANCE_FILE') as f: d = json.load(f)
d['deepseek']['balance_rmb'] = float('$2'.replace(',',''))
d['_last_processed'] = ''
with open('$BALANCE_FILE', 'w') as f: json.dump(d, f, indent=2, ensure_ascii=False)
print(f'DeepSeek balance set to ¥{float(\"$2\"):.2f}')
"

Technical Analysis

The second command-line argument, $2, is interpolated directly into source code passed to python3 -c. Shell quoting does not make this safe because the expanded value becomes part of the generated Python program.

An attacker who can control the DeepSeek balance argument can supply text that terminates the expected Python string literal and inserts additional Python statements. The injected statements execute when Python parses and runs the dynamically generated program. Numeric conversion does not provide effective validation because injected code can execute before a subsequent conversion error terminates the script.

This is an exploitable code-injection flaw rather than intended Skill behavior. Setting a numeric balance does not require constructing executable source code from user input.

Attack Path

  1. A user, automation rule, or agent invokes set-balance deepseek <value>.
  2. An attacker influences the supplied balance value, such as through copied instructions or another untrusted input source.
  3. The crafted value closes the Python string literal surrounding $2 and introduces additional Python statements.
  4. The shell expands $2 inside the multiline python3 -c argument.
  5. Python executes the injected statements with the privileges and environment of the user running the Skill.
  6. The injected code can access local files, credentials, process ...[truncated 1010 chars]
Remediation
View remediation

Remediation Suggestions

Do not interpolate command-line values into dynamically generated Python source. Pass the balance and file path as ordinary positional arguments:

bash
if [[ $# -ne 2 ]]; then
    echo "Usage: set-balance deepseek <rmb>" >&2
    exit 1
fi

python3 - "$BALANCE_FILE" "$2" <<'PY'
import json
import math
import sys

path = sys.argv[1]

try:
    value = float(sys.argv[2].replace(",", ""))
except ValueError:
    raise SystemExit("Balance must be numeric")

if not math.isfinite(value) or value < 0:
    raise SystemExit("Balance must be a finite, non-negative number")

with open(path, encoding="utf-8") as f:
    data = json.load(f)

data.setdefault("deepseek", {})["balance_rmb"] = value
data["_last_processed"] = ""

with open(path, "w", encoding="utf-8") as f:
    json.dump(data, f, indent=2, ensure_ascii=False)

print(f"DeepSeek balance set to ¥{value:.2f}")
PY

Additional hardening should include:

  1. Validate the exact number of arguments before referencing $2.
  2. Reject negative, non-finite, malformed, or implausibly large balances.
  3. Apply the same argument-passing approach to every value currently embedded in inline Python.
  4. Prefer a standalone Python script over python3 -c for maintainability and safer input handling.
  5. Add regression tests using quotes, newlines, semicolons, Python expressions, and shell metacharacters to verify that inputs are treated solely as data.
  6. Write balance updates atomically and restrict the balance file's permissions to the intended user.
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 (15)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The documented purpose is passive real-time cost monitoring, but the implementation findings indicate local balance mutation and missing actual usage-accounting logic. A skill that claims to monitor but instead modifies local accounting state can mislead users about costs, balances, or billing status and may cause incorrect operational decisions based on fabricated or stale data.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding

The skill advertises automatic execution on every assistant reply and references scripts that can write local files, invoke shell, and potentially perform network updates, but it declares no explicit tool scope or permissions. That creates an unnecessary trust gap: users and the platform cannot tell in advance what capabilities the skill will exercise, increasing the risk of unintended file mutation or external access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The skill says it works with zero configuration and auto-activates on every reply, but the description omits a clear warning that it updates local pricing and balance files. Silent state changes in an always-on skill reduce user awareness and can enable persistent tampering, inaccurate accounting, or hard-to-debug behavior across future sessions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This markdown file states that the skill reads transcript data and updates the balance file automatically, and later notes that balance.json is updated automatically. The description does not include any warning that the skill writes to local files or alters user-managed balance state, which is a user-data/system-integrity relevant behavior for markdown under SQP-2.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The documentation says the calibration tool 'Syncs with provider backends' and specifically documents 'DeepSeek (automatic API query)'. This is a network operation that may transmit account or usage-related data, but the markdown does not warn users about external requests, required credentials, or what information is sent.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The module docstring and usage text are written entirely in Chinese, which imposes a language choice in user-facing instructions without any opt-in or alternative locale. Under the policy, locale or language constraints should be optional or explicitly justified when they are user-facing.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest describes a cost-monitoring skill that shows token consumption and remaining balance after replies. While querying a provider balance API is consistent with that purpose, directly reaching into ~/.openclaw configuration and referenced secret files to extract credentials expands the skill into credential discovery/secret access that is not stated in the manifest.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code automatically loads a DeepSeek API key from ~/.openclaw/openclaw.json or a referenced secret file, then transmits it to the DeepSeek balance endpoint. Although there are internal comments, there is no user-facing prompt, log, or warning disclosing that local credentials will be accessed and used for a network request.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/calibrate.py (reported line 39)May include surrounding context.

python
# 调用 API
    import urllib.request
    req = urllib.request.Request(
        "https://api.deepseek.com/user/balance",
        headers={"Authorization": f"Bearer {api_key}"}
    )
    with urllib.request.urlopen(req, timeout=10) as resp:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code writes updated balance data to balance.json, changing persisted state on disk. Although the script has a brief usage docstring, there is no explicit warning, confirmation prompt, or user-facing disclosure that running the script will modify the local balance file, especially when --set-balance is used or when routine deductions occur.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code performs a direct write to a user file, replacing the contents of the balance data on disk. Although the header says the script modifies the balance file, there is no runtime confirmation, warning, or visible notice immediately before the write, so the safety-critical file modification lacks user disclosure in the code path itself.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This branch also performs a direct overwrite of the balance JSON file, changing persisted credit values. The operation affects user data on disk, but the code provides no confirmation prompt or explicit user-facing warning at the point of modification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This manifest-like JSON file contains only Chinese-language notes such as "余额文件,由 cost.py 自动扣减。每次真实对话后自动更新" and similar note fields, with no indication that language choice is optional. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

This JSON includes a Chinese locale source path (zh-CN), Chinese-language notes, and a fixed pricing window expressed as Beijing Time. That natural-language content imposes a specific language/locale context, but the file does not indicate that the skill is region-specific or that users can opt into another locale.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The natural-language instructions in the script are presented only in Chinese, which can impose a language requirement on users without opt-in or alternative locale support. This may conflict with language/locale policy when no choice or justification is provided.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.