Back to skill

Security audit

Token Stats

Security checks for vulnerabilities and agentic risk

Overview

This is mainly a local token-usage viewer, but its maintenance commands can modify PATH, update itself, and delete directories with insufficient safeguards.

Install only if you are comfortable with a tool that edits your shell PATH, creates persistent wrappers, reads local agent usage/history files, and can update or uninstall itself. Avoid custom --install-dir values for uninstall, review any directory it says it will remove, and treat CSV exports as untrusted when opening them in spreadsheet software.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
token_stats/file_manager.py:382
Finding

Arbitrary Recursive Directory Deletion Through User-Controlled Install Path

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
token_stats/exporters.py:616
Finding

CSV Formula Injection Through Untrusted Model Names

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
README.md:58
Finding

Unpinned Globally Installed ClawHub Dependency Creates Supply-Chain Exposure

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (58)

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

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

s above.

Cause 2: Ran setup but haven't opened a new terminal → setup writes PATH to system config. Open a new terminal for it to take effect.

Cause 3: setup PATH write failed → Re-run setup and check for errors. If needed, add PATH manually:

macOS (zsh):

bash
echo 'export PATH="$HOME/.token-stats/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc

Linux (bash):

bash
echo 'export PATH="$HOME/.token-stats/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

Windows (PowerShell, current session only):

powershell
$env:PATH += ';' + "$env:USERPROFILE\.token-stats\bin"

❓ Permission denied when running token-stats

macOS / Linux only. Cause: wrapper script lacks execute permission.

bash
chmod +x ~/.token-stats/bin/token-stats
# Or just re-run setup
python3 ~/skills/agent-usage-stats/token-stats.py setup

Windows users are not affected (.cmd files don't need execute permission).

Runtime issues

❓ My agent isn't showing

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

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

s above.

Cause 2: Ran setup but haven't opened a new terminal → setup writes PATH to system config. Open a new terminal for it to take effect.

Cause 3: setup PATH write failed → Re-run setup and check for errors. If needed, add PATH manually:

macOS (zsh):

bash
echo 'export PATH="$HOME/.token-stats/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc

Linux (bash):

bash
echo 'export PATH="$HOME/.token-stats/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

Windows (PowerShell, current session only):

powershell
$env:PATH += ';' + "$env:USERPROFILE\.token-stats\bin"

❓ Permission denied when running token-stats

macOS / Linux only. Cause: wrapper script lacks execute permission.

bash
chmod +x ~/.token-stats/bin/token-stats
# Or just re-run setup
python3 ~/skills/agent-usage-stats/token-stats.py setup

Windows users are not affected (.cmd files don't need execute permission).

Runtime issues

❓ My agent isn't showing

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

System-directory installation, global wrapper creation/deletion, PATH updates, config removal, and external update calls are materially different from simply displaying token statistics. In the context of an agent skill, this creates a trust gap where a low-risk utility may receive approval despite having the ability to change execution environment and remove files.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

System-directory installation, global wrapper creation/deletion, PATH updates, config removal, and external update calls are materially different from simply displaying token statistics. In the context of an agent skill, this creates a trust gap where a low-risk utility may receive approval despite having the ability to change execution environment and remove files.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

System-directory installation, global wrapper creation/deletion, PATH updates, config removal, and external update calls are materially different from simply displaying token statistics. In the context of an agent skill, this creates a trust gap where a low-risk utility may receive approval despite having the ability to change execution environment and remove files.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

System-directory installation, global wrapper creation/deletion, PATH updates, config removal, and external update calls are materially different from simply displaying token statistics. In the context of an agent skill, this creates a trust gap where a low-risk utility may receive approval despite having the ability to change execution environment and remove files.

Content

No source excerpt is available for this finding.

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · test_regression.py (reported line 46)May include surrounding context.

python
env: dict[str, str] | None = None, expect: list[str] | None = None,
            allow_fail: bool = False, cwd: Path | str | None = None) -> subprocess.CompletedProcess:
        print(f"$ {' '.join(str(c) for c in cmd)}")
        run_env = os.environ.copy()
        run_env.setdefault("PYTHONIOENCODING", "utf-8")
        if env:
            run_env.update(env)

Unvalidated Output Injection

High
Category
Output Handling
Confidence
95% confidence
Finding

Model output is used without validation or sanitization. Unvalidated output injected into downstream contexts (SQL, shell, HTML) enables injection attacks and arbitrary code execution.

Content

Scanner excerpt · token_stats/app.py (reported line 445)May include surrounding context.

python
calls_expr = "SUM(api_call_count)" if has_api_calls else "0"
            tools_expr = "SUM(tool_call_count)" if has_tool_calls else "0"
            cur = conn.execute(
                f"SELECT model, SUM(input_tokens) as inp, SUM(output_tokens) as out, "
                f"SUM(cache_read_tokens) as cache, {calls_expr} as calls, "
                f"{tools_expr} as tools, COUNT(*) as cnt "

Unvalidated Output Injection

High
Category
Output Handling
Confidence
95% confidence
Finding

Model output is used without validation or sanitization. Unvalidated output injected into downstream contexts (SQL, shell, HTML) enables injection attacks and arbitrary code execution.

Content

Scanner excerpt · token_stats/app.py (reported line 498)May include surrounding context.

python
calls_expr = "SUM(api_call_count)" if has_api_calls else "0"
            tools_expr = "SUM(tool_call_count)" if has_tool_calls else "0"
            cur = conn.execute(
                f"SELECT model, SUM(input_tokens) as inp, SUM(output_tokens) as out, "
                f"SUM(cache_read_tokens) as cache, {calls_expr} as calls, "
                f"{tools_expr} as tools, COUNT(*) as cnt "

Missing User Warnings

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code performs recursive deletion of install and legacy directories with no confirmation in this function. Destructive operations like shutil.rmtree are high risk because a wrong path, unexpected legacy path match, or maliciously influenced arguments could lead to irreversible data loss beyond the intended skill files.

Content

No source excerpt is available for this finding.

Unvalidated Output Injection

High
Category
Output Handling
Confidence
95% confidence
Finding

The finding is valid, though the root issue is not SQL output injection in the usual sense; it is unsafe code construction. The SQL and surrounding Python are assembled into a python3 -c string using interpolated values (linux_path, where), so attacker-controlled path or timestamp-derived content can alter the executed Python/SQL payload, leading to arbitrary code execution in WSL or unintended database queries.

Content

Scanner excerpt · token_stats/paths.py (reported line 137)May include surrounding context.

python
"cols={r[1] for r in c.execute('PRAGMA table_info(sessions)')};"
        "has_ac='api_call_count' in cols;has_tc='tool_call_count' in cols;"
        "ac='api_call_count' if has_ac else '0';tc='tool_call_count' if has_tc else '0';"
        "rows=[dict(r) for r in c.execute("
        "f'SELECT model,SUM(input_tokens) inp,SUM(output_tokens) out,SUM(cache_read_tokens) cache,'"
        "f'SUM('+ac+') calls,SUM('+tc+') tools,COUNT(*) cnt FROM sessions%s GROUP BY model')];"
        "sc=c.execute('SELECT COUNT(*) FROM sessions%s').fetchone()[0];"

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

md
| | `--compare` / `--a` / `--b` | Compare two periods |
| | `--now` / `--detail` | Current snapshot / detail mode, same as default stats |
| `--all` | | View **all** agents at once |
| | `setup` / `--setup` | Install to `~/.token-stats/`, create `~/.token-stats/bin/token-stats`, and add it to PATH |
| | `update` / `--update` | Update to the latest version |
| | `--uninstall` | Remove wrapper, install directory, and PATH entry |

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

The documented behavior says --uninstall automatically removes multiple classes of files and PATH entries across platforms, which is an autonomous destructive action. In the context of an installable agent skill, automatically deciding to delete install/history directories can cause unintended data loss or overbroad cleanup if path handling is wrong or users do not understand the scope.

Content

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

token-stats --uninstall

text

> `--uninstall` automatically removes wrappers, cleans PATH entries, deletes config files, removes `~/.token-stats/`, and clears ClawHub/history install directories such as `~/skills/agent-usage-stats` so reinstall can start cleanly. Works on all platforms.

---

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The documentation at L112 says users must manually delete ~/skills/agent-usage-stats/ to remove the ClawHub-downloaded files, but L602 states --uninstall automatically clears those install directories as well. These statements actively contradict each other about whether uninstall affects the original downloaded skill directory.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README documents an uninstall command that may automatically remove wrappers, PATH entries, config files, install directories, and ClawHub/history directories without a prominent warning before the command is presented. Destructive file deletion and environment modification are risky because users may run the command expecting a narrow uninstall and unintentionally lose downloaded skill content or local state.

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

Cause 2: Ran setup but haven't opened a new terminal → setup writes PATH to system config. Open a new terminal for it to take effect.

Cause 3: setup PATH write failed → Re-run setup and check for errors. If needed, add PATH manually:

macOS (zsh):

bash

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

❓ Export says "directory not found"

Cause: the directory path you entered doesn't exist. Create it first:

bash
mkdir -p ~/Desktop/my-data

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The description around '只读本机 SQLite / JSONL' and '本地账本' frames the skill as a read-only usage viewer. Yet the README documents operational commands that write into ~/.token-stats/, create global launchers, add PATH entries, and remove files/directories during uninstall, which is materially beyond passive statistics reading.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The README states token-stats '不联网、不查 API 后台,纯读当前设备上的数据文件', which communicates a strongly local, read-only scope. However, elsewhere the same file documents token-stats update and ClawHub/npm installation/update operations that necessarily contact remote package sources, so the documented behavior is broader than the stated 'no network' claim.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README describes uninstall behavior that removes wrappers, PATH entries, configuration, installation directories, and historical skill directories, but does not present a strong warning, confirmation step, or precise deletion scope at the point of use. Destructive file-removal operations can cause accidental data loss or overbroad cleanup if users do not understand exactly what will be deleted.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
81% confidence
Finding

The skill metadata declares no explicit tool scope or permissions, yet the referenced behavior includes file access, shell execution, environment access, and possible network/update operations. In an agent ecosystem, missing scope declarations weakens user consent and sandboxing expectations, making it easier for a seemingly simple stats skill to perform broader local actions than its description suggests.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest description on L03 forces a specific language presentation, and the rest of the skill documentation continues in Chinese. Under the policy, language constraints should either be optional for the user or clearly justified as region-specific, which is not stated here.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · test_regression.py (reported line 51)May include surrounding context.

python
if env:
            run_env.update(env)
        try:
            result = subprocess.run(
                [str(c) for c in cmd],
                capture_output=True,
                text=True,

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

This code file contains natural-language CLI documentation and help output that forces a specific language/locale for all users. Under the policy, locale constraints should either offer user opt-in/choice or be clearly justified as region-specific, which is not present here.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest description frames this skill as a read-oriented monitoring tool for selecting an AI assistant and viewing token usage. In addition to analytics, the code exposes setup, update, and uninstall flows that create/remove installation directories, global commands, and PATH entries, which is broader than the stated purpose of viewing usage statistics.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.