Back to skill

Security audit

Mpp mobula

Security checks for vulnerabilities and agentic risk

Overview

The skill is upfront about using a funded hot wallet for paid API calls, but its generic call path can be steered to an unintended host that can trigger automatic wallet payments.

Review before installing. Use only a very low-balance wallet, avoid exposing the generic call interface to untrusted or model-generated paths, and prefer waiting for a version that validates the Mobula origin, allowed endpoint paths, challenge currency/realm/expiry, trusted recipient, and cumulative spend limits before automatic signing.

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

Error
Location
src/mpp/tempo-client.ts:159
Finding

Arbitrary Network Origin and Untrusted Payment Recipient Enable Wallet Draining

Content
View full analysis
, privateKeyHex: Hex ): Promise { const url = new URL(`${MOBULA_BASE_URL}${path}`); Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v)); // First attempt — no auth const res1 = await fetch(url.toString()); ``` The recipient supplied by the remote HTTP 402 response is then used directly in the signed transaction: ```ts const memo = challenge.memo ?? buildAttributionMemo(challenge.id, challenge.realm); let txHash: Hex; try { txHash = await walletClient.writeContract({ address: USDC_E, abi: USDC_ABI, functionName: "transferWithMemo", args: [challenge.recipient as Hex, BigInt(challenge.amount), memo], }); } catch (err: any) { throw new Error(`Tempo tx failed: ${err.message ?? err}`); } ``` The generic CLI command accepts the path without validating that it is a normalized Mobula API path: ```ts case "call": { const [path, ...kvs] = rest; if (!path) { console.error('Usage: bun run start call [key=value ...]'); console.error('Example: bun run start call /api/2/wallet/activity wallet=0xabc'); process.exit(1); } const params: Record = {}; for (const kv of kvs) { const idx = kv.indexOf("="); if (idx > 0) params[kv.slice(0, idx)] = kv.slice(idx + 1); } const w = await requireCliWallet(); const data = await tempoFetch(path, params, w.privateKey); console.log(JSON.stringify(data, null, 2)) ...[truncated 2910 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
package.json:35
Finding

Unpinned Wallet Dependencies and Missing Lockfile Create Supply-Chain Exposure

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (18)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared purpose emphasizes pay-per-call API access, but the skill also creates and manages hot wallets, stores encrypted private keys, derives per-user wallet keys, and handles persistent secret material. That mismatch is security-relevant because users may approve a data-access skill without realizing it introduces custodial wallet management and local secret storage, which substantially raises financial and key-compromise risk.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
83% confidence
Finding

The README states that a wallet is saved persistently at ~/.mpp-skill/wallet.json, which means a hot wallet containing spend authority is stored on disk for future reuse. Persistent credential storage is risky because compromise of the host account or insufficient key protection can lead to unauthorized spending, and the agent context increases exposure by encouraging unattended or multi-user automation.

Content

Scanner excerpt · README.md (reported line 14)May include surrounding context.

md
cd mpp-skill
bun install

# 1. Create a Tempo wallet (saved at ~/.mpp-skill/wallet.json, chmod 600)
bun run start wallet-create

# 2. Fund it with USDC.e via the bridge link printed by step 1

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README explicitly describes creating a wallet, funding it, and then automatically signing and broadcasting on-chain payments for API calls, but it does not present a prominent warning that commands will spend real funds and submit irreversible blockchain transactions. In an agent-skill context, this is more dangerous because integrators may wire the skill into automated workflows and trigger spending without clear end-user awareness or consent.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Lines L09-L10 say the key is only used for signing and 'does not touch any network egress,' while L12 says it is 'not sent over RPC.' However, elsewhere in the same document the skill explicitly uses the decrypted key to sign a Tempo transaction and communicates with https://rpc.tempo.xyz (L53, L68). Even if the raw private key is not transmitted, the statement that it does not touch network egress is contradicted by the documented code path where it is used immediately before network submission of the signed transaction.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill describes network and shell-driven setup and runtime behavior but does not declare any explicit tool scope or allowed-tools boundary. In an agent environment, that omission can cause overbroad execution permissions, making it easier for the skill to invoke shell commands or network calls beyond what a user reasonably expects.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

The skill explicitly instructs creation of a persistent hot wallet and storage of encrypted wallet data plus a local decryption secret on disk. Even with encryption, session persistence of spend-capable credentials materially increases the blast radius of host compromise, agent compromise, backup leakage, or accidental reuse across contexts because the agent can continue making funded on-chain payments without fresh user approval.

Content

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

md
cd mpp-skill
bun install

# 2. Create a hot wallet (AES-256-GCM encrypted at ~/.mpp-skill/wallet.json,
#    encryption key at ~/.mpp-skill/.secret, both chmod 600)
bun run start wallet-create
# → prints address + bridge link

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill states that subsequent calls are automatic, but it does not present a prominent upfront warning that API requests will spend real funds from the user's wallet after setup. In an agent setting, hidden or underemphasized auto-spending can lead to unauthorized or unexpected micropayments, repeated balance drain, and poor user consent.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

const price = await userMobulaCall(userId, "/api/2/token/price", { asset: "bitcoin" });

text

Per-user wallets are stored at `.claude/claudeclaw/wallets/{userId}.json`, AES-256-GCM encrypted with a key derived from `HMAC-SHA256(WALLET_SECRET, userId)`. The secret is auto-generated once at `.claude/claudeclaw/wallet.secret` (chmod 600). Different users cannot decrypt each other's keys.

### Direct low-level call

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 14)May include surrounding context.

md
*
 * SECURITY:
 *  - Private key is AES-256-GCM encrypted at rest.
 *  - Encryption key is a 32-byte secret stored at ~/.mpp-skill/.secret (chmod 600),
 *    auto-generated on first wallet creation.
 *  - The plaintext private key only exists in memory inside this process,
 *    just long enough to sign a Tempo transaction.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SECURITY.md (reported line 18)May include surrounding context.

md
*
 * SECURITY:
 *  - Private key is AES-256-GCM encrypted at rest.
 *  - Encryption key is a 32-byte secret stored at ~/.mpp-skill/.secret (chmod 600),
 *    auto-generated on first wallet creation.
 *  - The plaintext private key only exists in memory inside this process,
 *    just long enough to sign a Tempo transaction.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SECURITY.md (reported line 19)May include surrounding context.

md
*
 * SECURITY:
 *  - Private key is AES-256-GCM encrypted at rest.
 *  - Encryption key is a 32-byte secret stored at ~/.mpp-skill/.secret (chmod 600),
 *    auto-generated on first wallet creation.
 *  - The plaintext private key only exists in memory inside this process,
 *    just long enough to sign a Tempo transaction.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

md
*
 * SECURITY:
 *  - Private key is AES-256-GCM encrypted at rest.
 *  - Encryption key is a 32-byte secret stored at ~/.mpp-skill/.secret (chmod 600),
 *    auto-generated on first wallet creation.
 *  - The plaintext private key only exists in memory inside this process,
 *    just long enough to sign a Tempo transaction.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · src/cli-wallet.ts (reported line 6)May include surrounding context.

ts
*
 * SECURITY:
 *  - Private key is AES-256-GCM encrypted at rest.
 *  - Encryption key is a 32-byte secret stored at ~/.mpp-skill/.secret (chmod 600),
 *    auto-generated on first wallet creation.
 *  - The plaintext private key only exists in memory inside this process,
 *    just long enough to sign a Tempo transaction.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The generic call subcommand lets a user invoke any /api/2/* endpoint while authenticating with the local wallet's private key, which exceeds the narrower capability description of prices, wallet positions, and market data. This creates a scope-expansion issue: consumers may trust the documented surface area, but the skill can be used to reach undocumented or future endpoints that may trigger higher-cost operations, expose additional data, or change payment behavior without explicit review.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill metadata says it provides crypto prices, wallet positions, and market data, but this code also exposes wallet activity/transaction retrieval. That expands the data access scope to potentially sensitive behavioral and financial history, which can surprise users and calling agents and enable privacy-invasive use beyond the declared purpose. Because calls are made with the user's own wallet-backed payment flow, the mismatch is more dangerous: an agent can cause users to pay for undisclosed access to transaction history.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 33)May include surrounding context.

json
"bun": ">=1.0.0"
  },
  "dependencies": {
    "viem": "^2.48.4"
  },
  "devDependencies": {
    "@types/bun": "latest"

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
70% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 36)May include surrounding context.

json
"viem": "^2.48.4"
  },
  "devDependencies": {
    "@types/bun": "latest"
  },
  "peerDependencies": {
    "bun": ">=1.0.0"

Unverifiable Dependency: bun has 2 known advisory(ies) (CVE-2025-8022 (bun vulnerable to OS Command Injection); CVE-2024-21548 (Bun has an Application-level Prototype Pollution vulnerability in the runtime na)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.