Back to skill

Security audit

MY/SG Invoice & Receipt Parser

Security checks for vulnerabilities and agentic risk

Overview

This paid invoice skill discloses billing, but its endpoint mainly charges a caller-supplied user ID and returns tax rates instead of actually parsing invoices.

Review this skill carefully before installing. It may be acceptable only if you are comfortable with a paid remote call that sends a user identifier and if the SkillPay billing layer independently authenticates users and prevents duplicate or unauthorized charges. Do not rely on this artifact alone for actual invoice OCR or structured document extraction.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (1)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/index.ts:20
Finding
Caller-Controlled Billing Identity Allows Potential Unauthorized Charges<![CDATA[ ## Vulnerability Details **File Location**: `src/index.ts:20-34` **Vulnerability Type**: Missing authorization for a sensitive billing operation **Risk Level**: High ### Vulnerable Code ```ts const body = await request.json() as { user_id: string; country?: "MY" | "SG"; }; if (!body.user_id) { return Response.json({ error: "user_id required" }, { status: 400 }); } const billing = await chargeUser({ userId: body.user_id, apiKey: env.SKILLPAY_API_KEY, priceUsdt: 0.02, skillName: "my-sg-invoice-parser", }); ``` ### Technical Analysis The public request handler obtains `user_id` directly from untrusted request JSON and uses it to perform a billing operation authenticated with the server-side `SKILLPAY_API_KEY`. The visible code does not authenticate the caller, verify ownership of the supplied billing identity, require a signed authorization token, or derive the user identity from a trusted session. The TypeScript type assertion on `request.json()` provides no runtime validation or authorization. Consequently, possession or discovery of another user's identifier may be sufficient to request a charge against that identity. Billing is part of the functionality declared in `SKILL.md`, so contacting the billing service and using the API key are necessary in principle. However, allowing callers to select the account to be charged exceeds least privilege unless the unavailable `../../shared/billing` implementation independently and reliably validates user authorization. The imported billing helper is outside the supplied project. Its endpoint, authorization controls, and handling of `SKILLPAY_API_KEY` could not be reviewed. The vulnerability is therefore directly confirmed at the endpoint authorization boundary, while successful financial exploitation depends on whether the external helper performs an additional authorization check. ### Attack Path 1. An attacker obtains or guesses another customer's `user_id`. 2. The attacker submits a ...[truncated 1341 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Authenticate every billing request** - Require a verified session, signed access token, or equivalent authentication mechanism before initiating a charge. - Reject anonymous requests to the billing endpoint. 2. **Do not trust a billing identity supplied in request JSON** - Derive the chargeable `userId` from authenticated server-side identity claims. - If a request includes `user_id`, compare it with the authenticated identity and reject mismatches. 3. **Require transaction-specific authorization** - Use short-lived, signed billing intents that bind the user, Skill name, price, expiration time, and unique nonce. - Verify the signature and all bound values before calling `chargeUser`. 4. **Add replay and duplicate-charge protection** - Require an idempotency key for each logical parsing transaction. - Persist completed transaction identifiers for an appropriate retention period and reject replays. - Ensure the downstream billing service also enforces idempotency. 5. **Apply abuse controls** - Rate-limit requests per authenticated user, account, and source. - Detect abnormal charge frequency and temporarily block suspicious activity. - Record security audit events without logging API keys or unnecessary personal data. 6. **Perform runtime input validation** - Validate the JSON body with a strict schema. - Enforce expected identifier format and length, reject unknown properties where practical, and handle malformed JSON safely. 7. **Harden the billing helper** - Confirm that `../../shared/billing` sends data only to the intended HTTPS billing endpoint. - Ensure it independently verifies authorization rather than treating possession of a user ID as authority to charge. - Limit the API key to this Skill, the fixed price, and only the billing operations required. - Rotate the key if exposure is suspected and prevent it from appearing in responses or logs. 8. **Add secur ...[truncated 254 chars]
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
Findings (7)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill claims multilingual invoice extraction capability, but the provided implementation details do not show actual OCR, document handling, or extraction logic; instead they focus on tax heuristics and remote tax-rate retrieval. This mismatch is dangerous because it can mislead integrators into trusting unsupported capabilities and obscure the fact that the only concrete action shown is a paid network call.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The skill claims multilingual invoice extraction capability, but the provided implementation details do not show actual OCR, document handling, or extraction logic; instead they focus on tax heuristics and remote tax-rate retrieval. This mismatch is dangerous because it can mislead integrators into trusting unsupported capabilities and obscure the fact that the only concrete action shown is a paid network call.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The skill’s stated purpose is invoice/receipt extraction, but the implementation does not parse invoices at all; it charges the user and returns tax rates instead. This capability mismatch is a strong indicator of deceptive behavior because users or calling systems may invoke the skill expecting document processing while actually triggering billing.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill instructs the agent to make a network request to an external endpoint, but it does not declare any explicit tool scope or network permission boundaries. This is dangerous because hidden or undeclared network behavior makes it harder for users and platforms to understand that external data transfer and remote side effects can occur, including billing-related actions.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The documentation tells the agent to POST a user identifier to a remote endpoint that charges billing, but it does not present a clear up-front warning, consent flow, or privacy disclosure. This is dangerous because it can lead to unauthorized paid actions and unnecessary disclosure of user-linked data to a third party before the user understands the consequences.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
Charging a user is not necessary for invoice parsing itself, and in this file it appears as the primary operation despite the skill being described as a parser. That unjustified payment capability increases the risk of unauthorized or deceptive monetization, especially in agent ecosystems where skills may be invoked automatically based on descriptions.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The code accesses billing credentials and initiates a charge without any user-facing disclosure or confirmation in the file’s behavior. In a skill presented as an invoice parser, silent charging is dangerous because it can cause unexpected financial impact and erode trust, even if the billing backend itself is technically functioning as designed.

Static analysis

No suspicious patterns detected.