Back to skill

Security audit

交易记录生成

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent local accounting tool, but it silently rewrites source financial CSV data and can carry untrusted spreadsheet formulas into generated workbooks.

Review this skill before installing if you rely on the original bank exports as audit records. Run it on copies of your source files, keep backups, and inspect generated workbooks before opening or sharing them, especially if any input file could contain formula-like text beginning with '='. Prefer adding dependency pinning and formula sanitization before routine use.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/交易记录.py:121
Finding
Untrusted spreadsheet data is written as executable formulas<![CDATA[ ## Vulnerability Details **File Location**: `scripts/交易记录.py:121-137`, `scripts/交易记录.py:169-179`, `scripts/交易记录.py:342-346`; `scripts/生成账目.py:405-426` **Vulnerability Type**: Spreadsheet formula injection **Risk Level**: High ### Vulnerable Code ```python # scripts/交易记录.py:121-137 ws_checking = wb.create_sheet(title='招行活期') ws_checking.append(['交易日期', '收入', '支出', '余额', '交易备注']) for row in checking_data: ws_checking.append([row['date'], row['income'], row['expense'], row['balance'], row['note']]) # 2. 招行理财 ws_finance = wb.create_sheet(title='招行理财') if finance_data: # 添加标题行(从原始数据获取) headers = ['委托状态', '委托日期', '代码', '货币', '交易类型', '委托数量', '成交价格', '委托金额', '交易金额', '已提业绩报酬', '确认份额日期', '资金到账日期', '合同号', '交易详情'] ws_finance.append(headers) for item in finance_data: ws_finance.append(list(item['raw'])) ``` ```python # scripts/交易记录.py:169-179 ws_corp.append([ date_str, convert_value(row[2]) if len(row) > 2 else None, # 收入(贷方) convert_value(row[1]) if len(row) > 1 else None, # 支出(借方) convert_value(row[3]) if len(row) > 3 else None, # 余额 row[6] if len(row) > 6 else '' # 账号/摘要 ]) ``` ```python # scripts/交易记录.py:342-346 else: for j, val in enumerate(row, 1): # 把 0 改为 None(显示为空) if val == 0: val = None cell = ws_print.cell(row=i, column=j, value=val) ``` ```python # scripts/生成账目.py:405-426 row_num = ws.max_row + 1 if row_data['balance_formula']: balance_val = row_data['balance_formula'] else: # 所有行都用公式:=上期 + 本行收入 - 本行支出 balance_val = f'=A{row_num-1}+F{row_num}-G{row_num}' row = [ balance_val, # A 列:余额 row_data['date'], # B 列:发生日期 row_data['cat1'], # C 列:分类 1 row_data['cat2'], # D 列:分类 2 row_data['cat3'], # E 列:分类 3 row_data['income'], # F 列:收入金额 row_data['expense'], # G 列:支出金额 h_value, # H 列:应付/应收/预收 row_data['note'], # I 列:备注 row_data['student'], # J 列:学员/单位 row_data['acco ...[truncated 2515 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Introduce a centralized function for writing imported text safely: ```python def safe_spreadsheet_text(value): if not isinstance(value, str): return value if value.startswith('='): return "'" + value return value ``` 2. Apply this function to every untrusted textual field before passing it to `append()` or assigning it to `Cell.value`, including: - Checking-account notes and dates. - Corporate-account summaries. - Every raw finance-workbook text field. - Notes and other textual fields copied by the accounting generator. 3. Do not propagate formulas from imported workbooks. Replace: ```python if row_data['balance_formula']: balance_val = row_data['balance_formula'] ``` with logic that discards imported formulas and calculates balances exclusively using internally generated, structurally fixed formulas. 4. Load source workbooks with `data_only=True` when only cached values are required. This reduces accidental formula propagation, although it must not replace output sanitization because cached values may be unavailable. 5. Separate trusted application formulas from imported values at the data-model level. For example, use a dedicated formula wrapper that can only be constructed by internal calculation code. 6. Add regression tests using notes and cells such as `=1+1`, `=HYPERLINK(...)`, and external-reference formulas. Verify that imported values are stored as literal strings while internally generated balance formulas remain formulas. ]]>

T08 · Insecure Dependencies

Note
Location
SKILL.md:43
Finding
Third-party dependencies are installed without version or integrity pinning<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:43-45` **Vulnerability Type**: Unpinned dependency installation **Risk Level**: Low ### Vulnerable Code ```bash pip install openpyxl xlrd ``` ### Technical Analysis The documented installation command requests the latest versions of `openpyxl` and `xlrd` available from the user's configured package index. It does not constrain package versions or verify package hashes. As a result, installations are not reproducible and the code may run against dependency versions that were never reviewed with the Skill. Although the names shown are established packages and there is no evidence of dependency confusion or typosquatting in the project, mutable resolution still exposes users to compromised future releases, compromised package-index infrastructure, or incompatible API changes. ### Attack Path 1. A user follows the installation command in `SKILL.md`. 2. `pip` resolves the package names against the user's configured index at installation time. 3. A newly compromised, malicious, or incompatible release is selected because no reviewed version is pinned. 4. Package installation code or imported runtime code executes under the privileges of the user running the Skill. 5. A malicious dependency could access the same local financial files and output directories available to the process. ### Impact Assessment A compromised dependency would execute with the privileges of the Python environment in which the Skill is installed or run. It could potentially read or modify bank-export files, generated accounting workbooks, and any other resources accessible to that user. There is no evidence that the currently named dependencies are malicious. This finding concerns the absence of version and integrity controls rather than a confirmed malicious package. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Add a dependency lock file containing reviewed, exact versions. 2. Generate and record cryptographic hashes for every package and transitive dependency. 3. Install dependencies using hash verification: ```bash python -m pip install --require-hashes -r requirements.txt ``` 4. Use a controlled package index and explicitly configure trusted repository URLs in deployment documentation. 5. Review and update pinned versions regularly to incorporate security fixes. 6. Run dependency vulnerability scanning in continuous integration and test the Skill against every dependency update before changing the lock file. 7. Prefer installation inside a dedicated virtual environment running with only the filesystem permissions required to process the selected input and output directories. ]]>
Vulnerability Patterns
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (3)

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script rewrites the source CSV in place, deleting comment lines and blank lines without creating a backup or requiring user confirmation. In a financial-record processing context, destructive modification of original input data can cause irreversible loss of audit information and can be abused by supplying a path to sensitive or canonical source files that the operator did not intend to alter.

Intent-Code Divergence

Low
Confidence
88% confidence
Finding
The docstring at L038 says the function will '统一逗号格式', implying delimiter normalization, but L043 replaces ',' with ',' which is a no-op. The function also writes the cleaned content back to the original file at L049-L050, which is a more significant side effect than the misleading normalization comment suggests.

Natural-Language Policy Violations

Low
Confidence
93% confidence
Finding
This Python file contains user-facing CLI descriptions and runtime messages entirely in Chinese, such as the argparse help text and printed status/output lines. Under the stated policy, forcing a specific language without user opt-in is a natural-language locale violation unless the tool documents a justified region-specific constraint or offers a choice.

Static analysis

No suspicious patterns detected.