Back to skill

Security audit

Cai Gun Gun

Security checks for vulnerabilities and agentic risk

Overview

This finance skill appears purpose-built rather than malicious, but it automatically duplicates sensitive financial records into the skill directory and has inconsistent storage messaging that users should review carefully.

Install only if you are comfortable with your transaction history, balances, merchants, notes, and config being stored both under ~/.cai-gun-gun/data and copied into the skill's data directory. Treat exported Excel files as sensitive, avoid importing untrusted spreadsheets, and confirm destructive actions carefully.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/tracker.py:46
Finding

Automatic Plaintext Duplication of Financial Data into a Potentially Synchronized Directory

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/tracker.py:719
Finding

Spreadsheet Formula Injection in Exported Excel Workbooks

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • 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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (19)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill documents capabilities that imply environment access and file read/write behavior, but it does not declare any explicit tool scope or permission boundaries. In a financial-records skill, this weakens reviewability and increases the chance the agent can access or modify local financial data in ways the user did not clearly authorize.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The trigger list includes broad everyday phrases such as '记账' and '查账单', which may cause the skill to activate unintentionally during normal conversation. Because the skill can read, write, import, export, and potentially clear financial records, accidental invocation can expose private data or lead to unintended state changes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill promotes third-party bill import but does not clearly warn that imported spreadsheets may contain highly sensitive personal financial information, including merchants, balances, dates, and account metadata. Users may provide such files without understanding retention, local copying, sync behavior, or the privacy exposure created by parsing them.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill describes automatic synchronization of financial data to a sync directory without a clear, prominent warning that sensitive records may be duplicated outside the primary storage location. Duplicating account and transaction data increases exposure, especially if the skill directory is backed up, synced, shared, or less protected than the main data directory.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The module description, user-facing command descriptions, help text, and output messages are written in Chinese, which effectively forces a specific language for interaction. There is no opt-in, alternative locale, or explanation that this skill is intentionally region-specific.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code automatically performs bidirectional copying of financial records between the local data directory and the skill directory for sync purposes. In an agent ecosystem where skill directories may be packaged, synced, or exposed differently than local private storage, this broadens the confidentiality and integrity boundary for sensitive financial data beyond what the manifest describes.

Content

No source excerpt is available for this finding.

Tainted flow: 'src' from os.environ.get (line 50, credential/environment) → shutil.copy2 (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/tracker.py (reported line 53)May include surrounding context.

python
src = PRIMARY_DATA_DIR / filename
            dst = SYNC_DATA_DIR / filename
            if src.exists():
                shutil.copy2(src, dst)
        return True
    except Exception as e:
        print(f"同步到skill目录失败: {e}", file=sys.stderr)

Tainted flow: 'src' from os.environ.get (line 50, credential/environment) → shutil.copy2 (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/tracker.py (reported line 67)May include surrounding context.

python
src = PRIMARY_DATA_DIR / filename
            dst = SYNC_DATA_DIR / filename
            if src.exists():
                shutil.copy2(src, dst)
        return True
    except Exception as e:
        print(f"同步到skill目录失败: {e}", file=sys.stderr)

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

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/tracker.py (reported line 207)May include surrounding context.

python
with open(sync_file, 'r', encoding='utf-8') as f:
                data = json.load(f)
                # 恢复到主目录
                with open(TRANSACTIONS_FILE, 'w', encoding='utf-8') as f:
                    json.dump(data, f, ensure_ascii=False, indent=2)
                sync_to_skill()  # 确保同步
                print(f"从同步目录恢复交易记录", file=sys.stderr)

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

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/tracker.py (reported line 221)May include surrounding context.

python
with open(sync_file, 'r', encoding='utf-8') as f:
                data = json.load(f)
                # 恢复到主目录
                with open(TRANSACTIONS_FILE, 'w', encoding='utf-8') as f:
                    json.dump(data, f, ensure_ascii=False, indent=2)
                sync_to_skill()  # 确保同步
                print(f"从同步目录恢复交易记录", file=sys.stderr)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

After saving transactions, the skill silently copies the data into the skill directory, creating an additional replica of sensitive financial records without an explicit user-facing notice at the time of write. Because bookkeeping data can include dates, merchants, notes, and account information, undisclosed replication materially increases privacy exposure.

Content

No source excerpt is available for this finding.

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

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/tracker.py (reported line 245)May include surrounding context.

python
try:
            with open(sync_file, 'r', encoding='utf-8') as f:
                data = json.load(f)
                with open(ACCOUNTS_FILE, 'w', encoding='utf-8') as f:
                    json.dump(data, f, ensure_ascii=False, indent=2)
                sync_to_skill()
                return data

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

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/tracker.py (reported line 261)May include surrounding context.

python
try:
            with open(sync_file, 'r', encoding='utf-8') as f:
                data = json.load(f)
                with open(ACCOUNTS_FILE, 'w', encoding='utf-8') as f:
                    json.dump(data, f, ensure_ascii=False, indent=2)
                sync_to_skill()
                return data

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

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/tracker.py (reported line 285)May include surrounding context.

python
try:
            with open(sync_file, 'r', encoding='utf-8') as f:
                data = json.load(f)
                with open(CATEGORIES_FILE, 'w', encoding='utf-8') as f:
                    json.dump(data, f, ensure_ascii=False, indent=2)
                sync_to_skill()
                return data

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

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/tracker.py (reported line 299)May include surrounding context.

python
try:
            with open(sync_file, 'r', encoding='utf-8') as f:
                data = json.load(f)
                with open(CATEGORIES_FILE, 'w', encoding='utf-8') as f:
                    json.dump(data, f, ensure_ascii=False, indent=2)
                sync_to_skill()
                return data

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

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/tracker.py (reported line 316)May include surrounding context.

python
def save_config(config: Dict):
    """保存配置(双存储)"""
    PRIMARY_DATA_DIR.mkdir(parents=True, exist_ok=True)
    with open(CONFIG_FILE, 'w', encoding='utf-8') as f:
        json.dump(config, f, ensure_ascii=False, indent=2)
    sync_to_skill()

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The export feature writes a full financial ledger to an Excel file on disk, which can disclose sensitive personal finance information if the location is shared, synced, or not expected by the user. Export itself is a legitimate feature, but the code provides no warning, safe default destination explanation, or privacy notice around file creation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill exposes a destructive clear operation that wipes all transactions and resets balances, but this capability is not disclosed in the manifest description. Hidden destructive functionality increases the risk of accidental or unauthorized data loss, especially in agent-driven contexts where users may not expect irreversible state changes.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documentation says data is stored locally and also describes automatic syncing to a skill directory, while the success template later says there is no cloud service and data is only local. For a finance tool, inconsistent storage claims can mislead users about where sensitive records are copied, retained, or recoverable, undermining informed consent and safe handling of financial data.

Content

No source excerpt is available for this finding.