Back to skill

Security audit

OpenClaw Usage Manager

Security checks for vulnerabilities and agentic risk

Overview

The skill largely matches its stated usage-management purpose, but it handles live account tokens, rewrites OpenClaw authentication, and can terminate local processes with insufficient safeguards.

Review this skill carefully before installing. Use it only on a trusted single-user machine, prefer a secrets manager, rotate any tokens used during testing, remove the port-killing alias or server behavior, and do not enable the cron auto-switcher until you are comfortable with it changing OpenClaw's active authentication profile automatically.

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 (5)

T09 · Insecure Skill Coding Practices

Error
Location
usage-dashboard/server.mjs:27
Finding

Shell Command Injection Through Configurable 1Password Item IDs

Content
View full analysis
/dev/null`, { encoding: "utf-8", timeout: 10000 } ); ``` ### Technical Analysis The configurable `itemId` value is interpolated directly into a command executed through a system shell. It is neither quoted nor validated before reaching `execSync`. The project documentation instructs users to replace the placeholder item IDs in the `ACCOUNTS` object. If an attacker can influence one of these values—for example, through a malicious configuration example or modified project copy—shell metacharacters such as `;`, `|`, command substitution, or redirection will be interpreted as shell syntax. The legitimate task only requires passing an item identifier to the `op` executable. Invoking a shell exceeds that requirement and unnecessarily creates a command-execution channel. ### Attack Path 1. An attacker supplies or recommends a crafted 1Password item ID, such as an identifier followed by a shell command. 2. The victim places that value in the `ACCOUNTS` configuration. 3. The victim launches the dashboard and requests usage information. 4. `getTokenFrom1Password()` interpolates the crafted value into the shell command. 5. The shell executes the injected command with the permissions of the dashboard process. ### Impact Assessment Successful exploitation provides arbitrary command execution under the operating-system account running the dashboard. The attacker could: - Read Claude and OpenClaw credentials accessible to the user. - Modify files in the user's home directory. - Alter OpenClaw configuration or authentication profiles. - Install user-level persistence. - Exfiltrate other locally accessible information. The vulnerabili ...[truncated 139 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
usage-switch/check.mjs:67
Finding

Authentication Profile Replaced With Potentially Insecure File Permissions

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
usage-switch/setup-tokens-simple.sh:20
Finding

Interactive Setup Passes Account Tokens Through Process Arguments

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
usage-switch/setup-tokens.sh:14
Finding

1Password Setup Creates Plaintext Token File Before Restricting Permissions

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
usage-switch/setup-tokens-simple.sh:20
Finding

Interactive Setup Creates Plaintext Token File Before Restricting Permissions

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (26)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

│ ├── check.mjs # Usage checker & auto-switcher │ ├── setup-tokens.sh # One-time setup (1Password → tokens.json) │ └── setup-tokens-simple.sh # One-time setup (interactive, no 1Password) ├── .gitignore # Excludes tokens.json, *.env └── README.md

text

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 28)May include surrounding context.

md
cp usage-switch/check.mjs ~/.openclaw/workspace/tools/usage-switch/

Session Persistence

Medium
Category
Rogue Agent
Confidence
93% confidence
Finding

The README explicitly instructs users to create tokens.json containing live sk-ant-... API tokens in plaintext under a predictable path. Even with chmod 600, plaintext credential storage materially increases exposure from local compromise, backups, shell history mistakes, accidental file reads by other tools, or misconfigured permissions.

Content

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

Copy the second token

text

#### Step 2: Create tokens.json manually / tokens.jsonを手動作成

```bash
# Create the directory if it doesn't exist

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

Set restrictive permissions (owner read/write only)

Why: prevents other users on the system from reading your API tokens

パーミッションを制限(所有者のみ読み書き可)— 他のユーザーからの読み取りを防止

chmod 600 ~/.openclaw/workspace/tools/usage-switch/tokens.json

text

> **Note for dashboard:** If using Option B, you'll need to modify `server.mjs` to read tokens from `tokens.json` instead of 1Password. The default dashboard uses 1Password CLI directly.

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 25)May include surrounding context.

bash
# 1. Clone and install
git clone https://github.com/Takao-Mochizuki/openclaw-usage-manager.git
mkdir -p ~/.openclaw/workspace/tools/usage-dashboard
mkdir -p ~/.openclaw/workspace/tools/usage-switch
cp usage-dashboard/server.mjs ~/.openclaw/workspace/tools/usage-dashboard/
cp usage-switch/check.mjs ~/.openclaw/workspace/tools/usage-switch/

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The documented alias force-kills any process listening on port 18800 using kill -9 before starting the dashboard. This can terminate unrelated local services without confirmation or cleanup, causing data loss or instability if that port is reused by another application.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code retrieves a token from 1Password by invoking the op CLI and later also executes a shell command to kill whatever process is using the configured port. While these operations are visible in code comments only at a very high level, there is no confirmation prompt or explicit user-facing disclosure that the skill will access credentials from 1Password and may terminate another local process.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · README.md (reported line 606)May include surrounding context.

md
}

async function fetchUsage(token) {
  const res = await fetch("https://api.anthropic.com/v1/messages", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${token}`,

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · usage-dashboard/server.mjs (reported line 42)May include surrounding context.

js
}

async function fetchUsage(token) {
  const res = await fetch("https://api.anthropic.com/v1/messages", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${token}`,

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 · usage-dashboard/server.mjs (reported line 42)May include surrounding context.

js
}

async function fetchUsage(token) {
  const res = await fetch("https://api.anthropic.com/v1/messages", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${token}`,

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

On port-conflict, the server unconditionally runs lsof -ti:${PORT} | xargs kill, which can terminate unrelated local processes bound to that port. For a usage dashboard, force-killing other processes is unnecessary and can cause denial of service, data loss, or disruption of security-sensitive local services.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script reads two local token stores and rewrites the active auth profile, which is a sensitive credential-management action. In a skill presented as a usage checker, modifying the live authentication profile creates significant risk of unauthorized account switching, accidental credential misuse, and disruption of the agent's security boundary if the token sources or files are tampered with.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

This finding duplicates the same outbound transmission behavior at the same line: the script makes an authenticated request to api.anthropic.com. Even when the destination is legitimate, sending credentials and request data off-host is security-relevant and should be treated as sensitive behavior in a skill that also reads and switches local auth tokens.

Content

Scanner excerpt · usage-switch/check.mjs (reported line 21)May include surrounding context.

js
async function getUsage(token) {
  try {
    const res = await fetch('https://api.anthropic.com/v1/messages', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

This finding duplicates the same outbound transmission behavior at the same line: the script makes an authenticated request to api.anthropic.com. Even when the destination is legitimate, sending credentials and request data off-host is security-relevant and should be treated as sensitive behavior in a skill that also reads and switches local auth tokens.

Content

Scanner excerpt · usage-switch/check.mjs (reported line 21)May include surrounding context.

js
async function getUsage(token) {
  try {
    const res = await fetch('https://api.anthropic.com/v1/messages', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script persists two API tokens to a local JSON file on disk, which creates a real secret-at-rest exposure if the workstation, home directory, backups, or synced files are accessed by another party. Although the script later restricts file permissions, it does not clearly warn the user that long-lived credentials will be stored locally, and the write occurs before permissions are tightened.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

md
json.dump(data, f, indent=2)
print('✅ tokens.json に保存完了')
"
chmod 600 "$HOME/.openclaw/workspace/tools/usage-switch/tokens.json"
echo "✅ セットアップ完了"

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 75)May include surrounding context.

md
json.dump(data, f, indent=2)
print('✅ tokens.json に保存完了')
"
chmod 600 "$HOME/.openclaw/workspace/tools/usage-switch/tokens.json"
echo "✅ セットアップ完了"

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · usage-switch/setup-tokens-simple.sh (reported line 28)May include surrounding context.

sh
json.dump(data, f, indent=2)
print('✅ tokens.json に保存完了')
"
chmod 600 "$HOME/.openclaw/workspace/tools/usage-switch/tokens.json"
echo "✅ セットアップ完了"

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · usage-switch/setup-tokens.sh (reported line 22)May include surrounding context.

sh
json.dump(data, f, indent=2)
print('✅ tokens.json に保存完了')
"
chmod 600 "$HOME/.openclaw/workspace/tools/usage-switch/tokens.json"
echo "✅ セットアップ完了"

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The cron setup specifies Schedule: 0 */3 * * * (Asia/Tokyo) as the configuration to use, which imposes a locale/timezone choice in natural-language instructions. The document does not indicate that this timezone is merely an example or that users should choose their own local timezone.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The document declares lang="ja", which sets a specific language/locale for the page. In this file there is no visible user opt-in, language selector, or documented justification that this dashboard is intended only for a Japanese audience.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
72% confidence
Finding

The top-level comment presents the tool as simply opening a localhost dashboard, but the implementation also contains destructive behavior that kills processes on port collision. This mismatch reduces user awareness and increases the likelihood of unexpected local impact.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The skill makes an HTTP request to the Anthropic API using a bearer token retrieved from 1Password. Although this is related to the dashboard's purpose, the file does not contain a clear user-facing warning that it will contact an external service and send authenticated usage-check requests for configured accounts.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The header frames the script as a usage checker, but it also performs state-changing credential switching by rewriting the auth profile. This mismatch is dangerous because it hides privileged behavior behind an innocuous description, increasing the chance that operators run it without realizing it can alter authentication state.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

All user-facing prompts and status messages in the script are written only in Japanese, with no option to choose another language. That creates a natural-language policy concern where the skill enforces a specific locale without user opt-in or documented justification.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access, suspicious.potential_exfiltration

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
usage-dashboard/server.mjs:29

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
usage-switch/check.mjs:7

Sensitive-looking file read is paired with a network send.

Warn
Code
suspicious.potential_exfiltration
Location
usage-switch/check.mjs:13