Back to skill

Security audit

my-pay

Security checks for vulnerabilities and agentic risk

Overview

This payment skill is mostly coherent, but it can submit payments without a final transaction-specific confirmation and exposes sensitive payment-link material too broadly.

Review before installing. Only use this skill if you trust the mypay-bot CLI and are comfortable giving it payment API and wallet-signing credentials. Do not proceed unless the workflow is changed to require a clear final confirmation of the exact transaction details before any submit-payment command, and avoid sharing full payment URLs or tokenized links unless you know they are safe to disclose.

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)

T08 · Insecure Dependencies

Warning
Location
scripts/install_mypay.py:64
Finding

Unverified Globally Installed Payment Dependency

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:85
Finding

Payment Submission Proceeds Without Explicit Transaction-Specific Confirmation

Content
View full analysis
" ``` Replace `` with the actual payment link obtained from the workflow. ``` ### Technical Analysis The mandatory workflow transitions directly from checking wallet status to submitting a payment. It does not require the agent to present the final transaction details to the user or obtain explicit, transaction-specific confirmation immediately before executing `submit-payment`. Intent inferred from conversation is not equivalent to authorization for a finalized transaction. The final recipient, merchant, amount, currency, fees, network, payment-link host, and expiration conditions may differ from the user's original understanding. Wallet readiness also proves only that the wallet can transact; it does not establish the user's approval of a specific transaction. The instructions additionally require the payment link to be taken from previous workflow output without specifying independent validation of its scheme, destination, embedded amount, recipient, or integrity. Ambiguous conversation context, compromised CLI output, or an attacker-controlled payment link could therefore lead to submission of an unintended transaction. ### Attack Path 1. A payment request is created from ambiguous, incomplete, stale, or attacker-influenced conversation context. 2. The workflow obtains or constructs a payment link whose recipient, amount ...[truncated 1036 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (8)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

There is a clear description-behavior mismatch. The declared purpose says this skill should be used for user intents involving payments, purchases, checkout, transfers, and transactions. However, the code chunk is strictly an environment/dependency checker for an npm package. It verifies npm availability, inspects the globally installed mypay-bot version, and instructs the user how to manually install or update it. It does not initiate payments, handle wallets, process orders, transfer money, or interact with financial resources. While dependency checking could be a supporting implementation detail inside a broader payment skill, the supplied code chunk’s actual primary purpose is operational setup validation, not payment execution. Therefore the description materially overstates and misrepresents the code’s actual behavior.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The trigger criteria are extremely broad, including many common commerce-related words and even cases where the user does not explicitly ask to pay. In the context of a payment skill with wallet credentials and submission commands, overbroad invocation can cause the agent to enter a payment flow unexpectedly and increase the risk of accidental financial actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill instructs the agent to submit a payment using a payment link but does not require an explicit final confirmation from the user immediately before execution. In a payment context, this creates a direct risk of unauthorized or accidental transactions, especially if the trigger fired broadly or prior steps inferred intent incorrectly.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill explicitly requires copying full URLs, query parameters, tokens, and hashes from tool output back to the user verbatim. Because this is a payment skill handling API-linked workflows and wallet operations, those values may include secrets, signed links, session tokens, or one-time authorization material that could enable replay, account misuse, or data leakage.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · scripts/install_mypay.py (reported line 25)May include surrounding context.

python
def run_cmd(cmd):
    """Run a shell command and return (returncode, stdout)."""
    try:
        result = subprocess.run(
            cmd, shell=True, capture_output=True, text=True, timeout=30
        )
        return result.returncode, result.stdout.strip()

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill invokes shell commands and depends on external binaries, but it does not declare an explicit tool scope such as allowed-tools or permissions. In a payment-oriented skill, missing tool restrictions increases the chance of broader-than-expected command execution and makes review and enforcement of least privilege harder.

Content

No source excerpt is available for this finding.

Unbounded Output

Medium
Category
Output Handling
Confidence
60% confidence
Finding

Output size or generation rate is not bounded. Unbounded output enables denial-of-service through resource exhaustion, log flooding, or context-window stuffing.

Content

Scanner excerpt · SKILL.md (reported line 110)May include surrounding context.

md
- **Preserve all links and images exactly**: Every URL, link, and image reference that appears
  in the output of any mypay-bot command MUST be copied in full — character for character,
  with no truncation, no summarization, no reformatting. This includes query parameters,
  tokens, hashes, and any other URL components. Display them to the user exactly as received.

- **Follow the step order strictly**: Step 0 -> Step 1 -> Step 2. Do not skip or reorder.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/install_mypay.py (reported line 25)May include surrounding context.

python
def run_cmd(cmd):
    """Run a shell command and return (returncode, stdout)."""
    try:
        result = subprocess.run(
            cmd, shell=True, capture_output=True, text=True, timeout=30
        )
        return result.returncode, result.stdout.strip()

Static analysis

No suspicious patterns detected.