T09 · Insecure Skill Coding Practices
- Location
analyzer.js:965- Finding
Full OpenClaw Configuration and Credentials Exposed Through JSON Output
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
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.
analyzer.js:965Full OpenClaw Configuration and Credentials Exposed Through JSON Output
analyzer.js:585Undisclosed Broad Access to All Agent and Web-Chat Transcripts
analyzer.js:790Session Identifiers Are Disclosed Despite the Truncation Guarantee
mdReport.js:93Unescaped Metadata Enables Markdown Instruction Injection
webDashboard.js:994Stored DOM XSS in the Local Web Dashboard
webDashboard.js:356Unauthenticated Cross-Origin SSE Endpoint Exposes Session and Billing Metadata
snapshotCard.js:137Snapshot and Dashboard Violate Declared Offline, No-Shell, and Write-Scope Guarantees
README.md:30Unpinned Remote npm Package Execution and Native Dependency Installation
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.
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.
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.
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.
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.
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.
},
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',
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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
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.
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.
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.
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.
Detected: suspicious.dangerous_exec, suspicious.env_credential_access