Snarky Expense Butler

Security checks across malware telemetry and agentic risk

Overview

This is a mostly coherent expense tracker, but its chart feature can send spending totals to OpenRouter despite claiming local-only, no-API behavior.

Install only if you are comfortable storing expense and location history in a local JSON file. Avoid the trend feature with OPENROUTER_API_KEY set unless you accept sending spending totals to OpenRouter, and review the data-file environment variables so the skill reads and writes only the intended private file.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (10)

Tainted flow: 'LOCK_FILE' from os.environ.get (line 13, credential/environment) → open (file write)

Medium
Category
Data Flow
Content
"""添加消费记录"""
    try:
        # === 文件锁临界区开始 ===
        with open(LOCK_FILE, 'a') as lock_f:
            fcntl.flock(lock_f.fileno(), fcntl.LOCK_EX)
            try:
                # 加载现有数据
Confidence
95% confidence
Finding
with open(LOCK_FILE, 'a') as lock_f:

Tainted flow: 'DATA_FILE' from os.environ.get (line 12, credential/environment) → open (file write)

Medium
Category
Data Flow
Content
data['metadata']['total_amount'] = sum(record['total'] for record in data['records'])

                # 保存文件
                with open(DATA_FILE, 'w', encoding='utf-8') as f:
                    json.dump(data, f, ensure_ascii=False, indent=2)
            finally:
                fcntl.flock(lock_f.fileno(), fcntl.LOCK_UN)
Confidence
98% confidence
Finding
with open(DATA_FILE, 'w', encoding='utf-8') as f:

Lp3

Medium
Category
MCP Least Privilege
Confidence
85% confidence
Finding
The skill declares itself as a local JSON bookkeeping tool, but the documented commands indicate access to environment variables, local file read/write, and possible network use for trend generation. Undeclared capabilities reduce transparency and can lead to users or orchestrators invoking a skill with broader privileges than expected, especially when personal financial data is involved.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding
The skill description omits materially relevant behaviors: generating periodic reports, modifying historical records via location backfill, and contacting an external API for trend-chart generation. This mismatch is dangerous because users may believe the tool is fully local and limited to simple bookkeeping, while in reality it can alter stored data and potentially send sensitive spending information off-device.

Context-Inappropriate Capability

Low
Confidence
81% confidence
Finding
The script allows the expense data path to be overridden via the EXPENSE_DATA_FILE environment variable, which expands its file-read capability beyond the local expected JSON file. If an attacker or untrusted caller can control the environment, they can make the script read arbitrary files, causing unintended disclosure of sensitive local data or parsing of attacker-chosen content. In an expense-reporting skill, this capability is not clearly necessary, so the context makes it more suspicious than a general-purpose CLI utility.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
The script goes beyond normal chart generation by probing local auth configuration under ~/.openclaw/openclaw.json to discover OpenRouter-related credentials. Even though it does not extract the key from the keychain in this implementation, inspecting unrelated local auth sources creates unnecessary credential-access behavior and expands the attack surface for a bookkeeping tool.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The tool sends user spending data to OpenRouter for chart generation, which is a clear external disclosure of sensitive financial metadata. In the context of an expense-tracking skill that users would reasonably expect to operate locally, this is more dangerous because transaction patterns, dates, and amounts can reveal personal habits without clear necessity.

Vague Triggers

Medium
Confidence
78% confidence
Finding
The trigger terms are broad enough to match ordinary conversations about spending, budgets, or consumption, which can cause unintended activation. In a skill that reads/writes personal finance records, accidental invocation can result in unintended data creation, disclosure, or confusing side effects.

Natural-Language Policy Violations

Medium
Confidence
72% confidence
Finding
Forcing Chinese-language interaction without user opt-in can lead to misunderstanding of prompts, confirmations, or outputs, especially for sensitive financial operations. Miscommunication in a bookkeeping skill increases the chance of incorrect entries, accidental disclosures, or users consenting to actions they did not fully understand.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
Expense data is transmitted to a third-party API without any explicit warning, consent prompt, or runtime confirmation. This creates a privacy and trust violation because users may believe they are using a local bookkeeping feature while their spending information is being sent off-device.

VirusTotal

66/66 vendors flagged this skill as clean.

View on VirusTotal