安全决策报告

openclaw-usage-manager

This is a legitimate dual-account Claude Max usage manager, but it stores API tokens unencrypted in plaintext files and modifies OpenClaw auth profiles with no declared credentials handling in SKILL.md — a significant doc-to-code mismatch for a credential-accessing tool.

安装决策优先 来源: 手动上传 扫描时间: 2026/4/4
文件 7
IOC 5
越权项 4
发现 5
最直接的威胁证据
高危 凭证窃取
API tokens stored in plaintext on disk

Both setup scripts write raw Bearer tokens (sk-ant-...) to ~/.openclaw/workspace/tools/usage-switch/tokens.json as unencrypted JSON. Even with chmod 600, the tokens are recoverable by any process running as the user. SKILL.md does not document this token storage model.

usage-switch/setup-tokens.sh:17

为什么得出这个结论

2/4 个维度触发
阻止
声明与实际能力

发现 4 项声明之外的能力或越权行为。

复核
隐藏执行与外联

提取到 5 个一般风险产物,需要结合上下文判断。

阻止
攻击链与高危发现

报告包含 0 步攻击链,另有 2 项高危或严重发现。

复核
依赖与供应链卫生

发现 1 项需要关注的依赖或供应链线索。

风险分是怎么被拉高的

Undeclared credential access +15

SKILL.md nowhere mentions that API tokens (sk-ant-...) are read from 1Password or stdin and written to plaintext ~/.openclaw/.../tokens.json, nor that check.mjs reads/writes ~/.openclaw/agents/main/agent/auth-profiles.json

Plaintext token storage +15

tokens.json contains raw Bearer tokens (sk-ant-...) stored unencrypted on disk. chmod 600 mitigates file permission risk but does not encrypt the contents.

Auth profile modification +10

check.mjs modifies ~/.openclaw/agents/main/agent/auth-profiles.json at runtime to perform account switching — undeclared elevated file write to a sensitive agent config path

Shell execSync in dashboard server +5

server.mjs uses child_process.execSync for 1Password CLI invocations and port killing — not declared in SKILL.md but scoped and documented in code

External URLs in README +-5

External URLs point to a named GitHub repo (Takao-Mochizuki/openclaw-usage-manager), a real company (5dmgmt.com), and legitimate 1Password CLI docs — consistent with a real project, not a typosquat or C2 channel

最关键的证据

高危 凭证窃取

API tokens stored in plaintext on disk

Both setup scripts write raw Bearer tokens (sk-ant-...) to ~/.openclaw/workspace/tools/usage-switch/tokens.json as unencrypted JSON. Even with chmod 600, the tokens are recoverable by any process running as the user. SKILL.md does not document this token storage model.

usage-switch/setup-tokens.sh:17
Document the token persistence model in SKILL.md. Consider encrypting tokens.json at rest using a tool like gpg or keychain-access, or rely solely on 1Password CLI retrieval at runtime (do not write tokens to disk).
高危 凭证窃取

Undeclared modification of OpenClaw agent auth profiles

check.mjs reads and rewrites ~/.openclaw/agents/main/agent/auth-profiles.json at runtime to perform account switching. This modifies the agent's active authentication configuration — a sensitive operation — with no declaration in SKILL.md.

usage-switch/check.mjs:61
Declare in SKILL.md that this skill reads and modifies OpenClaw agent auth profiles. This is critical information for users who rely on OpenClaw's own auth security model.
中危 文档欺骗

SKILL.md does not declare any credential handling, token storage, or auth profile access

SKILL.md describes a dashboard and auto-switcher but omits all credential operations: reading tokens from 1Password, storing them in tokens.json, and modifying auth-profiles.json. This doc-to-code mismatch is the highest-value security signal in this analysis.

SKILL.md:1
Add a 'Credential Handling' section to SKILL.md explaining: (1) tokens are read from 1Password or stdin, (2) stored unencrypted in tokens.json with chmod 600, (3) used to read/write auth-profiles.json for account switching.
中危 权限提升

Undeclared filesystem WRITE to OpenClaw agent directory

check.mjs writes to ~/.openclaw/agents/main/agent/auth-profiles.json — a path inside OpenClaw's own agent infrastructure. SKILL.md declares no filesystem access beyond 'browser dashboard'.

usage-switch/check.mjs:8
Declare filesystem:WRITE for OpenClaw agent config paths in SKILL.md's capability requirements section.
低危 代码混淆

Hardcoded placeholder 1Password item IDs in server.mjs

The dashboard server has hardcoded 'your-c1-item-id' and 'your-c2-item-id' placeholders in ACCOUNTS config. While these are clearly documented as placeholders, leaving them in production code with no validation could cause confusing errors.

usage-dashboard/server.mjs:19
Validate that opItemId values are not placeholder strings before invoking op CLI. This is low risk but improves operational robustness.

声明能力 vs 实际能力

文件系统 阻止
声明 NONE
推断 WRITE
setup-tokens.sh:17 writes to ~/.openclaw/workspace/tools/usage-switch/tokens.json; check.mjs:65 writes to ~/.openclaw/agents/main/agent/auth-profiles.json
网络访问 阻止
声明 NONE
推断 READ
server.mjs:58, check.mjs:28 POST to https://api.anthropic.com/v1/messages using Bearer tokens
命令执行 阻止
声明 NONE
推断 WRITE
setup-tokens.sh:1, setup-tokens-simple.sh:1 are shell scripts; server.mjs:148 uses execSync for port killing
浏览器 通过
声明 NONE
推断 READ
SKILL.md describes a 'browser dashboard' but browser:READ is not in the declared allowed-tools set
credential 阻止
声明 NONE
推断 WRITE
setup-tokens.sh reads from 1Password CLI (op item get --reveal); check.mjs:65 writes Bearer tokens into auth-profiles.json
环境变量 通过
声明 NONE
推断 READ
setup-tokens.sh:17, setup-tokens-simple.sh:18 pass C1_TOKEN/C2_TOKEN via os.environ to Python

可疑产物与外联

中危 外部 URL
https://x.com/5dmgmt/status/2032770037728113118

README.md:18

中危 外部 URL
https://openclaw.ai

README.md:92

中危 外部 URL
https://developer.1password.com/docs/cli/

README.md:95

中危 外部 URL
https://x.com/5dmgmt

README.md:653

中危 外部 URL
https://5dmgmt.com

README.md:655

依赖与供应链

包名版本来源漏洞备注
Node.js >= 18 unspecified runtime version runtime No package.json / package-lock.json found — no npm dependencies. Uses only built-in Node.js modules (http, crypto, child_process, fs, url, path)
1Password CLI (op) latest system binary External system binary invoked via execSync. SKILL.md declares '1Password CLI recommended' but does not verify installation. Failure is handled gracefully (returns null token)

文件构成

7 个文件 · 1333 行
Markdown 2 个文件 · 738 行JavaScript 2 个文件 · 293 行HTML 1 个文件 · 248 行Shell 2 个文件 · 54 行
需关注文件 · 6
usage-switch/setup-tokens.sh Shell · 23 行
API tokens stored in plaintext on disk
usage-switch/setup-tokens-simple.sh Shell · 31 行
README.md Markdown · 655 行
https://x.com/5dmgmt/status/2032770037728113118 · https://openclaw.ai · https://developer.1password.com/docs/cli/ · https://x.com/5dmgmt · https://5dmgmt.com
usage-dashboard/server.mjs JavaScript · 210 行
Hardcoded placeholder 1Password item IDs in server.mjs
usage-switch/check.mjs JavaScript · 83 行
Undeclared modification of OpenClaw agent auth profiles · Undeclared filesystem WRITE to OpenClaw agent directory
SKILL.md Markdown · 83 行
SKILL.md does not declare any credential handling, token storage, or auth profile access
其他文件 · index.html

安全亮点

All network requests target the legitimate Anthropic API endpoint (api.anthropic.com) — no C2 or exfiltration channels detected
Dashboard server binds to 127.0.0.1 only and implements CSRF token validation — good localhost-only design
Atomic file writes using tmp + renameSync pattern for auth-profiles.json — prevents corruption
tokens.json has chmod 600 applied — mitigates other-user file read risk
External URLs point to a named GitHub repo with a real company (5dmgmt.com) — consistent with a legitimate open-source tool, not typosquatting
setup-tokens.sh passes credentials via environment variables to Python rather than string interpolation — mitigates shell injection
server.mjs uses import.meta.url and path-safe file serving — no path traversal vectors
HTML dashboard uses DOM API (createElement) instead of innerHTML — mitigates XSS
AJAX calls to /api/usage require both CSRF token and localhost origin verification — defense in depth