Back to skill

Security audit

mpp

Security checks for vulnerabilities and agentic risk

Overview

This payments-development skill is coherent and not deceptive, but it deserves review because its examples can enable automatic spending and persist payment-related secrets.

Install only after reviewing the payment authority you are giving the agent. Pin package versions, run examples in a sandbox without production secrets or funded wallets, prefer scoped payment-aware fetch instances over global fetch patching, set low spend and session-deposit limits, use explicit origin allowlists, and protect .env, keychain accounts, mnemonics, and Lightning preimages like credentials.

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

T08 · Insecure Dependencies

Error
Location
SKILL.md:95
Finding
Unpinned Third-Party Packages Are Installed and Executed<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:95-97` **Related Locations**: `SKILL.md:136-140, 283-304, 406`; `references/cli.md:9-16, 46-49, 59-62, 82-119`; `references/stripe-method.md:164-176` **Vulnerability Type**: Unpinned dependency installation and immediate package execution **Risk Level**: High ### Vulnerable Code ```markdown Install: `npm install mppx viem` (mppx 0.8.15 requires `viem >= 2.54.0`). Validate the finished server end-to-end with `npx mppx validate http://localhost:3000`. ``` Additional affected examples include: ```bash pip install "pympp[tempo]" cargo add mpp --features tempo,server npx @stripe/link-cli spend-request create npx skills add tempoxyz/mpp -g ``` ### Technical Analysis The Skill recommends installing dependencies without exact version constraints and repeatedly uses `npx` to download and immediately execute packages. Although the metadata identifies versions against which the documentation was checked, those versions are not consistently enforced in the executable commands. An unqualified `npx mppx` or `npx @stripe/link-cli` invocation can resolve a mutable package version from the configured npm registry. The reviewed Skill therefore does not fully determine the code that will execute when a user follows its instructions. A compromised package publisher, registry account, transitive dependency, or malicious future release could alter the effective payload after this Skill has been audited. The affected commands may run in an environment containing wallet mnemonics, local account keys, system keychain access, Stripe credentials, API tokens, MCP configuration, and funded payment accounts. The global Skill synchronization command additionally imports mutable remote instructions into agent environments. ### Attack Path 1. An attacker compromises a referenced package publisher, registry account, or dependency. 2. The attacker publishes a malicious package version under the expected package name. 3. ...[truncated 1158 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin every dependency to an exact reviewed version, for example: ```bash npm install --save-exact mppx@0.8.15 viem@2.54.0 npx --package=mppx@0.8.15 mppx validate http://localhost:3000 ``` 2. Prefer a committed lockfile with integrity metadata and use reproducible installation commands such as `npm ci`. 3. Install command-line packages locally and execute the locked local binary rather than allowing `npx` to resolve the latest registry version. 4. Use `npm exec --offline` or an equivalent offline mechanism after dependencies have been reviewed and installed. 5. Pin Python and Rust dependencies in lockfiles or requirements files with hashes. 6. Review package provenance, signatures, publisher identity, and transitive dependencies before installation. 7. Do not install remote Skill content globally without displaying and reviewing the exact revision. 8. Run package installation and validation in a sandbox without production secrets, funded wallets, or broad filesystem access. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
references/python-sdk.md:50
Finding
Challenge-Signing Secret Is Automatically Persisted in a Plaintext .env File<![CDATA[ ## Vulnerability Details **File Location**: `references/python-sdk.md:50-58` **Vulnerability Type**: Insecure local secret storage **Risk Level**: Medium ### Vulnerable Code ```python app = FastAPI() # Auto-detects realm from env vars # Auto-generates secret_key to .env if not present mpp = Mpp.create( method=tempo( currency="<PATHUSD_TESTNET>", recipient="0xYourAddress", intents={"charge": ChargeIntent()}, ), ) ``` ### Technical Analysis The documented default behavior automatically generates a challenge-signing secret and writes it to a project-local `.env` file. The example does not require explicit secret management or document file permissions, source-control exclusion, access restrictions, or production deployment safeguards. A plaintext `.env` file can be exposed through accidental repository commits, CI artifacts, backups, container build contexts, shared workspaces, development-server file disclosure, or overly broad filesystem permissions. The signing secret is security-sensitive because it HMAC-binds challenge identifiers and helps establish the authenticity and integrity of payment challenges. Automatic implicit persistence is particularly risky because a user may not realize that secret material has been written to disk. ### Attack Path 1. A developer follows the documented Python setup without providing an explicit secret. 2. The SDK generates the signing key and stores it in `.env`. 3. The `.env` file is committed, copied into a container image, archived as a CI artifact, included in a backup, or read by another local process or user. 4. An attacker obtains the challenge-signing secret. 5. The attacker uses the secret to forge or tamper with challenge identifiers in environments sharing that key. 6. If the same key is reused across deployments, the compromise extends to all affected services until the key is rotated. ### Impact Assessment Disclosure can undermine challenge authenticity and allow ...[truncated 356 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require an explicit signing secret in production rather than relying on implicit generation: ```python import os secret_key = os.environ["MPP_SECRET_KEY"] mpp = Mpp.create(secret_key=secret_key, method=tempo(...)) ``` 2. Store production secrets in a dedicated secret manager or protected deployment environment. 3. If local `.env` generation is retained for development: - Create the file with mode `0600`. - Add `.env` and related variants to `.gitignore`. - Prevent inclusion in container build contexts and CI artifacts. - Emit a visible warning identifying the file and its sensitivity. 4. Use separate keys for development, testing, staging, and production. 5. Document key rotation and support an overlap period for safe replacement. 6. Avoid reusing the same signing key across unrelated services or tenants. 7. Add repository secret scanning to detect accidental commits. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
references/typescript-sdk.md:155
Finding
Process-Global Fetch Polyfill Grants Broad Automatic Payment Authority<![CDATA[ ## Vulnerability Details **File Location**: `references/typescript-sdk.md:155-190` **Related Locations**: `SKILL.md:102-114`; `references/typescript-sdk.md:209-228`; `references/lightning-method.md:43-75` **Vulnerability Type**: Excessively broad wallet-backed network interception **Risk Level**: High ### Vulnerable Code ```ts import { Fetch, Mppx } from 'mppx/client' // Standalone payment-aware fetch - no global mutation const paidFetch = Fetch.from({ methods: [tempo({ account })] }) const res = await paidFetch('https://api.example.com/data') // Explicit global install / uninstall Fetch.polyfill({ methods: [tempo({ account })] }) Fetch.restore() // Undo an instance's polyfill const mppx = Mppx.create({ methods: [tempo({ account })] }) Mppx.restore() ``` The documented default is: ```ts import { Mppx, tempo } from 'mppx/client' Mppx.create({ methods: [tempo()], polyfill: true, // default - wraps globalThis.fetch }) // All fetch calls now handle 402 automatically const res = await fetch('https://api.example.com/data') ``` The Skill further states that the browser same-origin restriction does not apply to non-browser environments: ```markdown **Breaking change (mppx 0.6.0):** polyfilled `fetch` in browsers no longer sends `Accept-Payment` on every request - it now defaults to **same-origin** only. Non-browser environments are unaffected. ``` ### Technical Analysis `Mppx.create()` wraps `globalThis.fetch` by default. This changes a process-global networking primitive and gives every caller in the same runtime access to automatic 402 negotiation backed by the configured wallet or account. In a server-side Node.js process, unrelated application code and third-party dependencies may use the same global `fetch`. Because the documented browser same-origin restriction does not protect non-browser environments, a request to an attacker-controlled origin can receive a syntactically valid payment challenge. The wrapper may then create a creden ...[truncated 1842 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Change the recommended and library default configuration to `polyfill: false`. 2. Use a dedicated payment-aware fetch instance: ```ts const paidFetch = Fetch.from({ methods: [tempo({ account, expectedChainId })], acceptPaymentPolicy: { origins: ['https://trusted-api.example.com'] }, maxPaymentRetries: 1, }) ``` 3. Require explicit origin allowlists in both browser and non-browser environments. 4. Reject redirects that cross from an approved origin to an unapproved origin. 5. Pin the expected network or chain ID and validate recipient addresses where supported. 6. Use delegated access keys with: - Low per-period spend limits - Short expiration - Recipient restrictions - Contract and function scopes - A documented revocation path 7. Require confirmation for mainnet payments or requests above a low threshold. 8. Set conservative `maxPaymentRetries`, `maxDeposit`, and session top-up limits. 9. Keep payment-capable networking in an isolated process that does not execute untrusted plugins. 10. Restore any global polyfill immediately after narrowly scoped use and avoid global mutation in libraries, shared workers, and test runners. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (79)

Credential Access

High
Category
Privilege Escalation
Content
## Accounts

```bash
npx mppx account create           # create (stored in system keychain)
npx mppx account list             # list all accounts
npx mppx account view             # show account address
npx mppx account default          # set the default account
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
## Accounts

```bash
npx mppx account create           # create (stored in system keychain)
npx mppx account list             # list all accounts
npx mppx account view             # show account address
npx mppx account default          # set the default account
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Missing User Warnings

High
Confidence
97% confidence
Finding
The session design uses the Lightning payment preimage as a bearer token, but the documentation does not clearly warn that anyone who obtains that preimage can reuse the session and spend its remaining value. Because bearer tokens are transferable by disclosure, accidental leakage through logs, traces, browser storage, proxies, or analytics can directly grant unauthorized access and consume paid balance.

Credential Access

High
Category
Privilege Escalation
Content
app = FastAPI()

# Auto-detects realm from env vars
# Auto-generates secret_key to .env if not present
mpp = Mpp.create(
    method=tempo(
        currency="<PATHUSD_TESTNET>",
Confidence
87% confidence
Finding
The documentation states that a secret key is auto-generated into a .env file if not present. Persisting newly generated secrets into a project-local .env can increase the chance of accidental exposure through source control, backups, logs, container images, or permissive filesystem access, especially when developers copy the example into real services.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill explicitly advertises transparent automatic payment handling on `fetch`, which can cause real spending to occur without a prominent consent or spend-warning step. In a payments skill, this is especially sensitive because copying the example into agent workflows could enable unattended charges to external endpoints.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The session example describes automatic channel opening and reuse with `maxDeposit`, which can create ongoing or repeated spend with little operator visibility. In this context, the danger is elevated because sessions can hold deposits and enable recurring microcharges, making accidental budget exhaustion more likely than a one-off payment.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Skill Enumeration

Medium
Category
Agent Snooping
Content
- [Stripe MPP docs](https://docs.stripe.com/payments/machine/mpp) - [Tempo docs](https://docs.tempo.xyz) - [x402 interop](https://mpp.dev/guides/use-mpp-with-x402) - [mpp vs x402](https://mpp.dev/mpp-vs-x402) - [governance](https://mpp.dev/governance)
- Agent wallets: [mpp.dev/tools/wallet](https://mpp.dev/tools/wallet) - Partner integrations: [Cloudflare Agents](https://mpp.dev/partner-integrations/cloudflare-agents), [Vercel AI SDK](https://mpp.dev/partner-integrations/vercel-ai-sdk), [MCP SDK](https://mpp.dev/partner-integrations/mcp-sdk), [OpenClaw](https://mpp.dev/partner-integrations/openclaw) - community [extensions](https://mpp.dev/extensions)
- Docs MCP: `claude mcp add --transport http mpp https://mpp.dev/api/mcp` (8 tools: `list_pages`, `read_page`, `search_docs`, `search_source`, `list_sources`, `list_source_files`, `read_source_file`, `get_file_tree`). Services MCP: [mpp.dev/mcp/services](https://mpp.dev/mcp/services)
- Upstream publishes its own machine-readable skill at `mpp.dev/.well-known/agent-skills/mppx/SKILL.md`; install via `npx skills add tempoxyz/mpp -g` or `mppx skills add`
Confidence
80% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Paid request (payment handled automatically)
npx mppx https://api.example.com/data

# POST with a JSON body
npx mppx -X POST -J '{"prompt":"hello"}' https://api.example.com/chat
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Paid request (payment handled automatically)
npx mppx https://api.example.com/data

# POST with a JSON body
npx mppx -X POST -J '{"prompt":"hello"}' https://api.example.com/chat
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Paid request (payment handled automatically)
npx mppx https://api.example.com/data

# POST with a JSON body
npx mppx -X POST -J '{"prompt":"hello"}' https://api.example.com/chat
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Paid request (payment handled automatically)
npx mppx https://api.example.com/data

# POST with a JSON body
npx mppx -X POST -J '{"prompt":"hello"}' https://api.example.com/chat
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Paid request (payment handled automatically)
npx mppx https://api.example.com/data

# POST with a JSON body
npx mppx -X POST -J '{"prompt":"hello"}' https://api.example.com/chat
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Paid request (payment handled automatically)
npx mppx https://api.example.com/data

# POST with a JSON body
npx mppx -X POST -J '{"prompt":"hello"}' https://api.example.com/chat
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Paid request (payment handled automatically)
npx mppx https://api.example.com/data

# POST with a JSON body
npx mppx -X POST -J '{"prompt":"hello"}' https://api.example.com/chat
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Paid request (payment handled automatically)
npx mppx https://api.example.com/data

# POST with a JSON body
npx mppx -X POST -J '{"prompt":"hello"}' https://api.example.com/chat
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Paid request (payment handled automatically)
npx mppx https://api.example.com/data

# POST with a JSON body
npx mppx -X POST -J '{"prompt":"hello"}' https://api.example.com/chat
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Paid request (payment handled automatically)
npx mppx https://api.example.com/data

# POST with a JSON body
npx mppx -X POST -J '{"prompt":"hello"}' https://api.example.com/chat
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Paid request (payment handled automatically)
npx mppx https://api.example.com/data

# POST with a JSON body
npx mppx -X POST -J '{"prompt":"hello"}' https://api.example.com/chat
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Paid request (payment handled automatically)
npx mppx https://api.example.com/data

# POST with a JSON body
npx mppx -X POST -J '{"prompt":"hello"}' https://api.example.com/chat
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# Paid request (payment handled automatically)
npx mppx https://api.example.com/data

# POST with a JSON body
npx mppx -X POST -J '{"prompt":"hello"}' https://api.example.com/chat
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
SKILL.md:360