Back to skill

Security audit

Invoice Agent

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent local invoice tool, but it needs Review because it handles sensitive billing data and generates unsafe HTML invoices from unescaped user-controlled fields.

Install only if you are comfortable with a local CLI storing billing and client data under ~/.invoice-agent. Treat generated HTML invoices as unsafe for untrusted or imported invoice data until fields are escaped, review reminder text before sending it yourself, and avoid using delete --force unless you have backups or deliberately intend permanent removal.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate_invoice.py:27
Finding

Stored HTML and JavaScript Injection in Generated Invoices

Content
View full analysis
{item['description']} {qty:g} {currency_symbol}{unit_price:,.2f} {currency_symbol}{amount:,.2f} """) return "\n".join(rows) ``` ```python replacements = { "{{INVOICE_ID}}": invoice_data.get("id", "INV-000000"), "{{STATUS}}": status.upper(), "{{STATUS_CLASS}}": status, "{{ISSUE_DATE}}": issue_date, "{{DUE_DATE}}": invoice_data.get("due_date", ""), "{{BUSINESS_NAME}}": invoice_data.get("business_name", "Your Business"), "{{BUSINESS_ADDRESS}}": invoice_data.get("business_address", ""), "{{BUSINESS_EMAIL}}": invoice_data.get("business_email", ""), "{{CLIENT_NAME}}": invoice_data.get("client_name", ""), "{{CLIENT_ADDRESS}}": invoice_data.get("client_address", ""), "{{CLIENT_EMAIL}}": invoice_data.get("client_email", ""), "{{ITEMS_ROWS}}": generate_item_rows(invoice_data.get("items", []), currency_symbol), "{{SUBTOTAL}}": f"{invoice_data.get('subtotal', 0):,.2f}", "{{TAX_RATE}}": f"{invoice_data.get('tax_rate', 0):g}", "{{TAX_AMOUNT}}": f"{invoice_data.get('tax_amount', 0):,.2f}", "{{TOTAL}}": f"{invoice_data.get('total', 0):,.2f}", "{{CURRENCY_SYMBOL}}": currency_symbol, "{{PAYMENT_TERMS}}": invoice_data.get("payment_terms", "Net 30"), "{{NOTES}}": invoice_data.get("notes", "Thank you for your business!"), "{{GENERATED_DATE}}": datetime.now().strftime("%B %d, %Y at %I:%M %p"), "{{BRAND_COLOR}}": ...[truncated 2653 chars]
Remediation
View remediation
``` 7. Add regression tests using payloads containing `

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/reminders.py:148
Finding

Terminal Escape-Sequence Injection Through Invoice Data

Content
View full analysis
inv["due_date"]: overdue = " ⚠️ OVERDUE" print(f" {inv['id']} | {inv['client_name']:20s} | {inv['currency']} {inv['total']:>10.2f} | {inv['status']:8s} | Due: {inv['due_date']}{overdue}") print(f"\nTotal: {len(invoices)} invoice(s)") ``` From `scripts/invoice.py`, lines 165-169: ```python total_overdue = sum(i["total"] for i in overdue) print(f"⚠️ {len(overdue)} overdue invoice(s) — Total: {total_overdue:.2f}\n") for inv in overdue: days_late = (datetime.now() - datetime.strptime(inv["due_date"], "%Y-%m-%d")).days print(f" {inv['id']} | {inv['client_name']:20s} | {inv['currency']} {inv['total']:>10.2f} | Due: {inv['due_date']} ({days_late} days late)") ``` From `scripts/reminders.py`, lines 148-166: ```python if not overdue: print("No overdue invoices found. 🎉") return print(f"Found {len(overdue)} overdue invoice(s):\n") for inv in overdue: reminder = generate_reminder(inv) print(f"{'='*60}") print(f"Invoice: {inv['id']} | Client: {inv['client_name']}") print(f"Amount: {inv['currency']} {inv['total']:,.2f} | Days Late: {reminder['days_late']}") print(f"Reminder Level: {reminder['level'].upper()}") print(f"{'='*60}") print(f"To: {reminder['to']}") print(f"Subject: {reminder['subject']}\n") print(reminder['body']) print(f"\n{'='*60}\n") ``` ### Technical Analysis Several commands print persisted invoice fields directly to an interactive terminal. Relevant fields include client names, email addresses, invoice identifiers, currency values, business details, and reminde ...[truncated 1880 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/invoice.py:23
Finding

Sensitive Invoice Records Are Created Without Explicit Restrictive Permissions

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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents a comprehensive invoice and payment management skill, but the supplied code only performs HTML invoice generation from an existing JSON input file. It does not create invoices from natural language, track invoices or payments, detect overdue status, send reminders, escalate reminders, compute summaries, or manage workflows. While the code does support a limited aspect of the description—HTML invoice generation and basic multi-currency symbol rendering—it materially underdelivers relative to the declared primary purpose. There is no evidence of cloud/API use, which is consistent with the local-storage claim, but the main mismatch is that the implementation is only a narrow invoice renderer rather than a full invoice management system.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code substantially matches the general domain of local invoice management and does support several declared features: local-only storage, multi-currency fields, tax calculations, overdue tracking, status management, and financial summaries. However, key advertised capabilities are absent. The implementation is a command-line CRUD tool, not a natural-language skill. It does not generate HTML invoices, does not send payment reminders, and contains no reminder escalation mechanism. Export functionality is limited to JSON rather than professional HTML invoices. Because these are prominent, user-facing features in the declared description rather than minor implementation details, the description overstates the actual behavior, so this should be flagged as a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The code implements only a narrow subset of the declared functionality: overdue invoice detection and payment reminder generation with escalation levels, using locally stored JSON data. It does align with parts of the description about payment reminders, overdue tracking, multi-currency display, and local storage. However, it does not create invoices from natural language, manage invoices broadly, calculate taxes, generate HTML invoices, or produce financial summaries/revenue reports. Therefore the declared description materially overstates the actual behavior of this code chunk.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This markdown file describes a destructive command, including delete --force, but does not include a user warning about permanence, data loss, or the need for caution before use. Because markdown files should warn about behaviors that can affect user data or system integrity, this omission is a safety concern.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The module docstring and implemented commands show support for create, list, update, summary, overdue, delete, export, and config, with export writing invoice data as JSON. There is no code for generating HTML invoices, sending reminders, or handling escalation levels, so the actual behavior falls materially short of key manifest claims.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The tool permits permanent deletion of non-draft invoices when --force is supplied, without any confirmation prompt, dry-run, undo capability, or audit trail. In a financial-management context, accidental or misuse-driven deletion can destroy accounting records and interfere with billing, dispute resolution, or compliance obligations.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This manifest file says the skill can 'Generate invoices from natural language' and gives a single example phrase, but it does not define explicit trigger boundaries, activation constraints, or negative examples. In a manifest, that kind of broad natural-language invocation description can overlap with ordinary requests about billing and make the skill's activation scope ambiguous.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The description states that the skill can create invoices, send smart payment reminders with automatic escalation, track overdue payments, and calculate tax, all of which can affect financial records and external communications. The markdown/manifest-style description provides promotional detail but no user-facing warning about reviewing invoice data, reminder content, or escalation behavior before use.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The skill persists invoice and client billing data to a local file, but the description does not present this as an explicit user warning near usage. Because invoice data commonly contains sensitive business and personal information, silent persistence can lead to unintended retention, local disclosure, backup propagation, or exposure on shared systems.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The document hard-codes lang="en", which is a natural-language locale choice embedded in the file. Under the policy, forcing a specific language without user opt-in or a documented region-specific justification is a locale policy violation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The create command requires explicit flags such as --client and --items, and items must be supplied in a rigid "description|quantity|unit_price" format. No parsing of free-form natural language descriptions is implemented in this file, which does not match the stated natural-language creation capability.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.