Back to skill

Security audit

My finance agent

Security checks for vulnerabilities and agentic risk

Overview

The skill is a simple expense tracker, but it gives unclear storage and credential expectations for sensitive company expense data.

Review before installing. Use it only if local CSV storage of company expense records is acceptable, do not assume Google Drive sync is implemented, and avoid providing Google Drive credentials unless the package is updated to actually use them with clear scope. Treat exported CSV files as potentially unsafe if expense fields can come from untrusted people.

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

Warning
Location
finance_agent.py:42
Finding
Spreadsheet Formula Injection in CSV Reports## Vulnerability Details **File Location**: `finance_agent.py`, lines 42-48; CSV generation at lines 72-73; file export at lines 91-93 **Vulnerability Type**: CSV formula injection **Risk Level**: Medium ### Vulnerable Code ```python self.expenses.append( { "Date": date, "Category": category, "Amount": amount, "Description": description, } ) ``` ```python if output_format == "csv": return df.to_csv(index=False) ``` ```python if data: with open(output_path, "w") as f: f.write(data) ``` ### Technical Analysis The `category` and `description` parameters are accepted without validation or output neutralization. The `amount` parameter can also contain an unexpected string because Python type annotations do not enforce runtime types. These values are passed directly to Pandas and serialized into CSV output. CSV escaping protects the file structure but does not neutralize spreadsheet formulas. If an attacker supplies a value beginning with a formula indicator such as `=`, `+`, `-`, or `@`, spreadsheet applications may interpret the cell as a formula when a user opens the exported report. A malicious description could, for example, contain a spreadsheet formula that creates an external hyperlink, performs an external data request in supporting software, or misrepresents financial values. The exact result depends on the spreadsheet application and its security configuration. ### Attack Path 1. An attacker or untrusted user submits an expense with a formula-prefixed `category`, `description`, or improperly typed `amount`. 2. `add_expense()` stores the supplied value without neutralizing spreadsheet control characters. 3. `_save_expenses()` or `generate_expense_table("csv")` serializes the malicious value into CSV. 4. `export_report()` writes the generated content to a report file. 5. A finance employee opens that CSV file in spreadsheet softw ...[truncated 947 chars]
Remediation
## Remediation Suggestions 1. Validate all parameters at runtime rather than relying only on type annotations: - Require `category` and `description` to be strings. - Parse `amount` as a finite decimal value. - Reject NaN, infinity, and unexpected object types. 2. Before spreadsheet-oriented CSV export, neutralize text cells whose first non-whitespace character is `=`, `+`, `-`, or `@`. 3. Prefix dangerous text values with an apostrophe or apply another neutralization strategy compatible with the intended spreadsheet clients. 4. Apply neutralization only to spreadsheet export copies if exact raw values must be retained internally. 5. Document whether generated CSV files are intended for spreadsheet use. 6. Add tests covering formula-prefixed values, leading whitespace, tabs, carriage returns, and all user-controlled fields. 7. Consider generating a format with explicit cell typing, while still applying appropriate protections for that format. Example defensive helper: ```python def spreadsheet_safe(value): if isinstance(value, str): normalized = value.lstrip() if normalized.startswith(("=", "+", "-", "@")): return "'" + value return value safe_df = df.map(spreadsheet_safe) return safe_df.to_csv(index=False) ```

T08 · Insecure Dependencies

Note
Location
SKILL.md:13
Finding
Unpinned Third-Party Dependencies Permit Non-Reproducible Installation## Vulnerability Details **File Location**: `SKILL.md`, lines 13-18 **Vulnerability Type**: Unpinned third-party dependencies **Risk Level**: Low ### Vulnerable Configuration ```yaml install: - kind: uv package: pandas bins: [] - kind: uv package: tabulate bins: [] ``` ### Technical Analysis The installation metadata declares `pandas` and `tabulate` without exact versions, hashes, or a referenced lock file. Each installation can therefore resolve to whatever package versions are available from the configured package index at that time. The package names correspond to the documented implementation and there is no evidence in the reviewed project that they are intentionally malicious or typosquatted. Nevertheless, the mutable dependency resolution prevents reproducible builds and expands supply-chain exposure. A future compromised, vulnerable, or behaviorally incompatible release could be installed without any change to the audited project. ### Attack Path 1. A dependency account, distribution artifact, package index, or upstream release becomes compromised, or a vulnerable release becomes the latest resolvable version. 2. A user installs the skill after that release becomes available. 3. The unpinned declarations resolve to the affected package version. 4. Package installation hooks or imported dependency code execute in the installation or skill runtime environment. 5. Malicious dependency code would operate with the privileges of the user or service installing and running the skill. This path is conditional on an upstream or package-distribution compromise; no such compromise was observed in the audited files. ### Impact Assessment If the dependency supply chain were compromised, code from the affected package could execute with the privileges of the skill installation or runtime process. Its scope could include expense data and any files, environment variables, or network resources ...[truncated 260 chars]
Remediation
## Remediation Suggestions 1. Pin each dependency to an explicitly reviewed version. 2. Maintain a lock file generated by the selected package manager. 3. Require cryptographic hashes for downloaded distributions where the installation system supports them. 4. Use a trusted, explicitly configured package index and disable unintended fallback indexes. 5. Review transitive dependencies and run automated vulnerability scanning during continuous integration. 6. Update dependency pins through a controlled process that includes testing and security review. 7. Store the immutable dependency specification with the project so installations reproduce the audited environment. Example version-pinned metadata: ```yaml install: - kind: uv package: pandas==<reviewed-version> bins: [] - kind: uv package: tabulate==<reviewed-version> bins: [] ``` Replace the placeholders with versions that have been tested and reviewed; do not select versions without checking current security advisories.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (4)

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding
The documentation claims Google Drive persistence and summary-table/reporting behavior that the described implementation does not actually provide, instead relying on local CSV writes. This mismatch can mislead users about where sensitive expense data is stored and what protections or processing are applied, leading to unsafe handling of financial information.

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill performs file-writing behavior but does not declare any tool scope or permissions boundary in the manifest. This weakens reviewability and can cause the runtime or user to underestimate that the skill persists data to disk, which is especially relevant for financial records.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill handles potentially sensitive company expense data and persists it to local CSV and purportedly Google Drive, but the description does not clearly warn users about this storage behavior. Without an upfront notice, users may provide confidential financial data without understanding retention, synchronization, or exposure risks.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The user-facing skill description and usage instructions are written entirely in Chinese, while the manifest does not indicate that the skill is region-specific or that language selection is optional. This can violate language/locale policy when a specific language is imposed without user opt-in.