Back to skill

Security audit

OpenClaw Model Usage (Linux)

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a local usage reporter, but it reads OpenClaw session logs, can inspect conversation text, and silently saves usage history, so users should review it before installing.

Install only if you are comfortable with a local script reading your OpenClaw session store and saving aggregate usage history under ~/.openclaw/workspace/skills/model-usage-linux. Review or remove the shipped state files before use, and treat the tool as able to inspect some conversation text for channel classification even though no network exfiltration was observed.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (2)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/usage.py:95
Finding

Unnecessary Access to Private Conversation Content During Channel Detection

Content
View full analysis
200: break line = line.strip() if not line: continue obj = json.loads(line) if obj.get("type") != "message": continue msg = obj.get("message", {}) content = msg.get("content", []) if isinstance(content, list): text = " ".join([c.get("text", "") for c in content if isinstance(c, dict)]) else: text = str(content) text_lower = text.lower() # Strong signals if "[QQBot]" in text or "qqbot" in text_lower: return "QQ" if "openclaw-weixin" in text_lower or "[微信]" in text or "wechat" in text_lower: return "WeChat" if "telegram" in text_lower or "@D4rchr0w_bot" in text: return "Telegram" if text.startswith("[cron:"): return "cron" if "heartbeat" in text_lower and "checklist" in text_lower: return "main" # /reset without channel prefix usually means main if text.startswith("/reset") and not any(x in text for x in ["[QQBot]", "[cron:", "[微信]"]): return "main" except Exception: pass return "unknown" ``` ### Technical Analysis The skill is documented as a token-usage and cost analyzer. Most of that function can be implemented using session metadata, filenames, mod ...[truncated 2029 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
last_usage.json:1
Finding

Operational Usage and Spending Telemetry Included in the Published Package

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Rogue AgentSelf-Modification, Session Persistence
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (9)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill instructs execution of a local Python script and references reading session files, but it does not declare any tool scope such as permissions or allowed-tools. That creates an authorization gap: an agent may use file access broader than a reviewer or runtime expects, increasing the chance of unintended local file reads or writes when the skill is invoked.

Content

No source excerpt is available for this finding.

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 · SKILL.md (reported line 31)May include surrounding context.

md
Shows per-model breakdown:
- Turns (assistant replies)
- Input / output tokens
- Cache read / write tokens
- Cost in USD

Sessions live at: `~/.openclaw/agents/main/sessions/*.jsonl`

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest describes a Linux replacement for usage and cost tracking by parsing session JSONL files, which implies read-oriented analytics over existing session logs. This code additionally creates and updates reset_offsets.json and last_snapshot.json to maintain cross-run state, extending behavior beyond simple parsing/reporting.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
55% 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 · scripts/usage.py (reported line 322)May include surrounding context.

python
CNY_RATE = 7.2

# Load previous data for incremental comparison
prev_file = os.path.expanduser('~/.openclaw/workspace/skills/model-usage-linux/last_usage.json')
prev_data = {}
if os.path.exists(prev_file):

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The stated purpose is to answer token usage and cost questions from session JSONL data. In addition to reading logs, the script reads and later rewrites last_usage.json to support incremental comparisons, which is a persistent-history feature not mentioned in the manifest description.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest frames the skill as a parser of session JSONL files for usage and cost summaries. Persisting aggregated channel/model totals into last_usage.json introduces stateful historical tracking across executions, which is a broader behavior than the description communicates.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

This code updates persistent JSON files (reset_offsets.json and last_snapshot.json) under the user's workspace, but there is no confirmation prompt, user-facing log, or warning near the write operations. Because the script otherwise appears to be an analyzer, silently mutating state can be unexpected to users.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

Most user-facing output strings are fixed in Chinese, which imposes a specific language/locale on users without any opt-in or configuration mechanism. This is a natural-language policy concern because the script does not offer language selection or explain that it is intentionally region-specific.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script writes last_usage.json containing aggregated usage history, but there is no visible warning, print, or comment that informs the user this analysis run persists data. For a reporting script, silently storing historical state may affect user expectations about privacy and local data changes.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.