Back to skill

Security audit

Clawculator

Security checks for vulnerabilities and agentic risk

Overview

This is a relevant OpenClaw cost analyzer, but it under-discloses sensitive local data access and has output paths that can expose configuration, identifiers, or third-party network metadata.

Review carefully before installing. The cost-analysis goal is legitimate, but the skill should more clearly disclose transcript and web-chat scanning, avoid returning raw config in JSON, redact identifiers consistently, remove external font loads, and narrow triggers. Do not share generated reports without checking for sensitive names, IDs, tokens, or commands, and avoid running the optional dashboard or unpinned npx examples on sensitive systems until these issues are fixed.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (8)

T09 · Insecure Skill Coding Practices

Error
Location
analyzer.js:965
Finding

Full OpenClaw Configuration and Credentials Exposed Through JSON Output

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
analyzer.js:585
Finding

Undisclosed Broad Access to All Agent and Web-Chat Transcripts

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
analyzer.js:790
Finding

Session Identifiers Are Disclosed Despite the Truncation Guarantee

Content
View full analysis
0) findings.push({ severity: 'high', source: 'sessions', message: `${orphaned.length} orphaned session(s) — still holding tokens on paid models`, detail: orphaned.map(s => `${s.key}: ${s.tokens.toLocaleString()} tokens ($${s.cost.toFixed(4)})` ).join('\n '), ...FIXES.ORPHANED_SESSIONS }); if (large.length > 0) findings.push({ severity: 'medium', source: 'sessions', message: `${large.length} session(s) with >50k tokens per conversation`, detail: large.map(s => `${s.key}: ${s.tokens.toLocaleString()} tokens` ).join('\n '), ...FIXES.LARGE_SESSIONS }); ``` Markdown output prints those details unchanged: ```js lines.push(`**${f.message}**`); lines.push(''); if (f.detail) lines.push(`${f.detail}`); ``` ### Technical Analysis Session-table rendering truncates long keys, but the finding construction path embeds full identifiers before output formatting. Markdown and terminal reports therefore disclose complete keys for orphaned or large sessions. Session keys may encode channel names, user identifiers, group identifiers, cron names, or other operational information. The vulnerability is particularly relevant because the documented Skill workflow instructs an AI agent to return the full Markdown report inline. ### Attack Path 1. A session has a sensitive key and is classified as orphaned or exceeds the token threshold. 2. The user invokes the documented `node run.js --md` command. 3. The analyzer inserts the full key into `finding.detail`. 4. The Markdown generator pr ...[truncated 505 chars]
Remediation
View remediation

T01 · Skill Instruction Hijacking

Error
Location
mdReport.js:93
Finding

Unescaped Metadata Enables Markdown Instruction Injection

Content
View full analysis
0) lines.push(`**Monthly cost:** $${f.monthlyCost.toFixed(2)}/month`); if (f.fix) { lines.push(''); lines.push(`**Fix:** ${f.fix}`); } ``` ### Technical Analysis Agent IDs, hook names, cron names, skill names, model values, and session keys come from mutable local OpenClaw files. These strings are inserted directly into Markdown syntax. An attacker who can influence one of those values can inject headings, links, images, code blocks, or natural-language instructions. This is an indirect instruction-hijacking risk because `SKILL.md` directs the calling agent to return the full generated Markdown report inline. The generated report may consequently contain attacker-controlled instructions in a trusted tool-result context. ### Attack Path 1. An attacker causes a session, agent, ...[truncated 826 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
webDashboard.js:994
Finding

Stored DOM XSS in the Local Web Dashboard

Content
View full analysis
Waiting for API calls...'; return; } tbody.innerHTML = state.sessions.slice(0, 8).map(s => { const costColor = s.cost > 5 ? 'var(--red)' : s.cost > 0.5 ? 'var(--amber)' : 'var(--green)'; return '' + '' + (s.name.length > 18 ? s.name.slice(0,16)+'…' : s.name) + '' + '' + (s.model || '—') + '' + '' + s.messages + '' + '' + fmtCost(s.cost) + '' + ''; }).join(''); } ``` Persisted leaderboard and live-feed data are handled similarly: ```js el.innerHTML = data.slice(0, 5).map((msg, i) => { const rankClass = i === 0 ? 'rank-1' : i === 1 ? 'rank-2' : i === 2 ? 'rank-3' : 'rank-n'; const time = new Date(msg.timestamp).toLocaleTimeString(); return '
' + '
' + (i+1) + '
' + '
'+fmtCost(msg.cost)+'
' + '
' + msg.session_name + ' · ' + (msg.model||'').split('/').pop() + ' · ' + time + '
' + '
' + fmtTokens(msg.total_tokens) + ' tok' + (msg.cache_write > 10000 ? '
' + fmtTokens(msg.cache_write) + ' cache' : '') + '
' + '
'; }).join(''); ``` ### Technical Analysis ...[truncated 1551 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
webDashboard.js:356
Finding

Unauthenticated Cross-Origin SSE Endpoint Exposes Session and Billing Metadata

Content
View full analysis
({ id, name: s.name, model: s.model, cost: s.cost, messages: s.messages, tokens: s.tokens, lastSeen: s.lastSeen, })).sort((a, b) => b.cost - a.cost), peakCostPerMsg, avgCostPerMsg: today.messages > 0 ? today.cost / today.messages : 0, }; } ``` The SSE endpoint allows every origin and requires no authorization: ```js if (url.pathname === '/api/stream') { res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive', 'Access-Control-Allow-Origin': '*', }); res.write(`data: ${JSON.stringify({ type: 'init', today: getTodaySummary(), recent: recentEvents.slice(0, 20) })}\n\n`); sseClients.add(res); req.on('close', () => sseClients.delete(res)); return; } ``` The service uses a predictable local address: ```js server.listen(port, '127.0.0.1', () => { console.log(` 🦞 Dashboard: \x1b[1m\x1b[36mhttp://localhost:${port}\x1b[0m`); ``` ### Technical Analysis Loopback binding prevents ordinary remote hosts from directly connecting, but it does not protect localhost services from a webpage running in the user’s browser. The fixed port and wildcard CORS policy allow an attacker-controlled web origin to establish an `EventSource` connection. The initialization and subsequent broadcasts expose full session IDs, names, model information, costs, timestamps, an ...[truncated 963 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
snapshotCard.js:137
Finding

Snapshot and Dashboard Violate Declared Offline, No-Shell, and Write-Scope Guarantees

Content
View full analysis
/dev/null || xdg-open "http://localhost:${port}" 2>/dev/null`); ``` ### Technical Analysis The snapshot command is directly documented in `SKILL.md`, but its file write is omitted from the declared write list. Opening the generated HTML as instructed causes the browser to contact Google Fonts. The bundled web dashboard similarly imports remote fonts and invokes a shell command to open a browser. The shell command uses an internally generated numeric port rather than direct user-controlled input, so no command-injection exploit was confirmed. The issue is inaccurate disclosure and unnecessary privilege rather than arbitrary command execution. ### Attack Path 1. The user invokes the documented `--snapshot` command. 2. The Skill writes `clawculator-snapshot.html` despite the statement that only `--md` writes files. 3. The output instructs the user to open the generat ...[truncated 829 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
README.md:30
Finding

Unpinned Remote npm Package Execution and Native Dependency Installation

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (35)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

This is the most serious mismatch: if the code starts an HTTP server, watches files continuously, uses SQLite/native modules, launches a browser via child_process, and exposes API/SSE endpoints, then the skill is operating far beyond a simple offline cost analyzer. Those behaviors substantially expand attack surface: local service exposure, persistent data storage, continuous monitoring of user files, command execution, and browser launch all introduce opportunities for privacy loss or abuse. In the context of a user-invocable skill advertised as bundled/offline, this discrepancy is highly dangerous because it defeats informed consent and least privilege expectations.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

This is the most serious mismatch: if the code starts an HTTP server, watches files continuously, uses SQLite/native modules, launches a browser via child_process, and exposes API/SSE endpoints, then the skill is operating far beyond a simple offline cost analyzer. Those behaviors substantially expand attack surface: local service exposure, persistent data storage, continuous monitoring of user files, command execution, and browser launch all introduce opportunities for privacy loss or abuse. In the context of a user-invocable skill advertised as bundled/offline, this discrepancy is highly dangerous because it defeats informed consent and least privilege expectations.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

This is the most serious mismatch: if the code starts an HTTP server, watches files continuously, uses SQLite/native modules, launches a browser via child_process, and exposes API/SSE endpoints, then the skill is operating far beyond a simple offline cost analyzer. Those behaviors substantially expand attack surface: local service exposure, persistent data storage, continuous monitoring of user files, command execution, and browser launch all introduce opportunities for privacy loss or abuse. In the context of a user-invocable skill advertised as bundled/offline, this discrepancy is highly dangerous because it defeats informed consent and least privilege expectations.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

This is the most serious mismatch: if the code starts an HTTP server, watches files continuously, uses SQLite/native modules, launches a browser via child_process, and exposes API/SSE endpoints, then the skill is operating far beyond a simple offline cost analyzer. Those behaviors substantially expand attack surface: local service exposure, persistent data storage, continuous monitoring of user files, command execution, and browser launch all introduce opportunities for privacy loss or abuse. In the context of a user-invocable skill advertised as bundled/offline, this discrepancy is highly dangerous because it defeats informed consent and least privilege expectations.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The trigger phrase 'snapshot' is highly ambiguous and likely to collide with ordinary user language. Because this mode is described as producing a shareable grade card, accidental invocation could expose account usage characteristics or generate disclosure-oriented output when the user did not intend to share billing-related information. In a skill that accesses local usage/session data, such an underspecified trigger materially increases privacy risk.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

The skill embeds a destructive shell command, rm ~/.openclaw/agents/main/sessions/sessions.json, as a recommended fix. In agent ecosystems that may surface or auto-run suggested commands, this creates a command-injection-by-design hazard and can cause data loss or unsafe file deletion if copied, executed blindly, or adapted to a different environment.

Content

Scanner excerpt · analyzer.js (reported line 86)May include surrounding context.

js
},
  ORPHANED_SESSIONS: {
    fix: 'Delete sessions.json to clear orphaned sessions — they auto-rebuild on next use',
    command: 'rm ~/.openclaw/agents/main/sessions/sessions.json',
  },
  LARGE_SESSIONS: {
    fix: 'Reduce root-level .md files in your workspace to shrink session context size',

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The card explicitly claims '100% offline' and 'your data never leaves your machine' while the HTML includes an external Google Fonts import. This is dangerous because it creates a deceptive privacy guarantee: users may open potentially sensitive cost-analysis snapshots believing no network traffic occurs, when in fact a third party is contacted and can observe access metadata.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill metadata explicitly says nothing is fetched at runtime, but the dashboard injects an external Google Fonts import. That causes outbound network access, leaks usage metadata such as IP/user agent/referrer context to a third party, and breaks the trust boundary promised by the package description.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

The README instructs users to execute npx clawculator without pinning a specific package version. Because npx resolves the latest published package by default, a compromised maintainer account, malicious new release, or dependency hijack could cause users to execute unreviewed code at install/runtime. The skill context increases risk because the tool is explicitly marketed for easy one-command execution.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

This usage example invokes npx clawculator without a pinned version, which allows execution of whatever version is current on the package registry at the time of use. If the package or publishing pipeline is compromised, users may run attacker-controlled code simply by following the documentation.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

The README promotes npx clawculator --md without constraining the package version. That creates a supply-chain execution risk because the command may fetch and run a newly published or tampered package version at invocation time.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

Using npx clawculator --report without a version pin exposes users to untrusted future package updates. In practice, documentation-driven copy/paste can turn a registry compromise into immediate code execution on analyst workstations.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

The unpinned npx clawculator --json example permits fetching the latest package version dynamically. That is dangerous because even a benign utility becomes an execution vector if a malicious version is published later.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

This example combines unpinned npx execution with writing output to a file, but the primary issue is still remote code execution risk via package resolution to the latest version. The offline/deterministic claims in the README do not mitigate the initial package fetch and execution path.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

The command npx clawculator --config=/path/to/openclaw.json is unpinned and may execute an attacker-controlled package version if the registry artifact changes. Given that the command processes local configuration files, compromise could also expose sensitive local data handled by the tool.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

The npx clawculator --help example is also an unpinned remote execution path. Even seemingly harmless commands like --help still require package resolution and startup code execution, so the attack surface remains the same.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

This JSON piping example uses npx clawculator --json without a fixed version, so a user following the README may execute whatever package is currently served from the registry. The presence of jq does not change the initial risk: the code has already run before its output is filtered.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

The command npx clawculator in the HTML output section is another unpinned package execution instruction. Repeated promotion of unpinned npx amplifies exposure because many users will copy the first command they see without reviewing supply-chain implications.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

This command again instructs users to run an unpinned package. In the context of a security-adjacent analysis tool, users may run it on systems containing configuration files, API keys, and logs, so registry compromise could have meaningful local impact.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The README says users can type clawculator in OpenClaw webchat to invoke the skill, but it does not provide any negative examples or activation constraints beyond the bare phrase. In a chat-driven agent environment, a single common noun-like command without explicit scope guidance can create ambiguity about when the skill should activate versus when the term is merely being discussed.

Content

No source excerpt is available for this finding.

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

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

md
mkdir -p ~/clawd/skills/clawculator

BASE=https://raw.githubusercontent.com/echoudhry/clawculator/main/skills/clawculator
curl -o ~/clawd/skills/clawculator/SKILL.md      $BASE/SKILL.md
curl -o ~/clawd/skills/clawculator/run.js         $BASE/run.js
curl -o ~/clawd/skills/clawculator/analyzer.js    $BASE/analyzer.js
curl -o ~/clawd/skills/clawculator/reporter.js    $BASE/reporter.js

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill declares no explicit tool scope or permissions, yet its documented behavior includes reading sensitive local files and invoking Node to execute bundled code. Even if the code is intended to be offline, the absence of declared permissions reduces transparency and makes it harder for users or platforms to constrain filesystem, environment, shell, or potential network access. Given the static note that code capabilities include env, network, and shell, this mismatch increases the risk of over-privileged execution.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Broad trigger phrases like 'check my costs' or 'cost report' can cause accidental invocation in unrelated conversations, leading the skill to read local billing/session files without the user clearly intending that action. The risk here is not code execution itself, but unintended access to potentially sensitive local data because the activation language is too generic.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
webDashboard.js:34

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
webDashboard.js:106