Back to skill

Security audit

SNAP Private Payments

Security checks for vulnerabilities and agentic risk

Overview

This is a plausible Solana private-payments skill, but it can move funds from broad natural-language commands without a clear confirmation step.

Review this skill carefully before installing. It should add strict transaction previews, explicit user confirmation for deposits and withdrawals, exact dependency pinning, and clearer disclosure of viewing-key, note, RPC, and relayer privacy implications.

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
SKILL.md:15
Finding
Unpinned Third-Party SDK Installation Creates Supply-Chain Risk## Vulnerability Details **File Location**: `SKILL.md:15` and `SKILL.md:41` **Vulnerability Type**: Unpinned npm dependency **Risk Level**: Medium ### Vulnerable Code ```yaml install: npm install snap-solana-sdk ``` ```text ## Setup npm install snap-solana-sdk ``` ### Technical Analysis The installation instructions retrieve `snap-solana-sdk` without specifying an exact reviewed version. The supplied project also contains no package manifest or lockfile that constrains the resolved version or verifies its integrity. Consequently, the code installed by this command may change after the Skill has been reviewed. If the package, its publishing account, or one of its transitive dependencies is compromised, a later installation could retrieve malicious code. npm packages can also define lifecycle scripts that execute during installation. This finding does not establish that the current `snap-solana-sdk` package is malicious. It identifies an unsafe dependency-resolution practice that exposes users to a mutable supply-chain component. ### Attack Path 1. An attacker compromises the npm package, its maintainer account, or a transitive dependency. 2. The attacker publishes a malicious version under the same package name. 3. A user follows the documented `npm install snap-solana-sdk` instruction. 4. npm resolves the unconstrained package to the attacker-controlled release. 5. Malicious lifecycle scripts or imported runtime code execute in the installation or agent process. ### Impact Assessment Successful exploitation could execute arbitrary code with the privileges of the user running npm or the agent. Depending on that account's access, the malicious dependency could read environment variables, wallet-related material available to the process, local files, or network credentials, and could alter transactions handled by the Skill. The affected scope is limited by the operating-system permissions and secrets avail ...[truncated 46 chars]
Remediation
## Remediation Suggestions - Pin the SDK to an exact reviewed version, such as `snap-solana-sdk@x.y.z`, rather than using an unconstrained package name. - Add a package manifest and commit a lockfile containing npm integrity hashes. - Use `npm ci` in deployment and installation workflows so dependency resolution cannot silently change. - Review both direct and transitive dependencies before updating the lockfile. - Use automated dependency scanning and package provenance verification. - Disable npm lifecycle scripts with `--ignore-scripts` when the SDK does not require them. - Run installation and the agent under a dedicated, least-privileged account without unnecessary access to wallet keys or unrelated secrets.

T09 · Insecure Skill Coding Practices

Error
Location
snap-skill.ts:28
Finding
Ambiguous Natural-Language Matching Can Trigger Unintended Financial Transactions## Vulnerability Details **File Location**: `snap-skill.ts:28-42` and `snap-skill.ts:120-122` **Vulnerability Type**: Unsafe financial-command parsing **Risk Level**: High ### Vulnerable Code ```typescript if (isDepositCommand(normalized)) { const amount = extractAmount(command); if (amount === null) { throw new Error( "SNAP OpenClaw deposit requires an amount, for example: deposit 0.1 SOL into SNAP pool" ); } const deposit = await context.snapClient.deposit(pool, amount); const poolInfo = await context.snapClient.getPoolInfo(pool); return `Deposited ${formatAssetLabel(poolInfo)} into SNAP. Deposit index ${ deposit.depositIndex }.`; } ``` ```typescript function isDepositCommand(command: string): boolean { return /(?:deposit|shield)/i.test(command); } ``` The amount is independently extracted from the first numeric substring: ```typescript function extractAmount(command: string): number | null { const match = command.match(/(\d+(?:\.\d+)?)/); return match ? Number(match[1]) : null; } ``` ### Technical Analysis Deposit intent is recognized whenever the input contains either `deposit` or `shield` anywhere in the text. The parser then treats the first numeric substring anywhere in the command as the transaction amount. It does not require a strict command grammar, an explicit execution verb at the beginning of the request, a denomination associated with the number, or transaction confirmation. Deposit detection is evaluated before fee-estimate detection. Therefore, a command such as `estimate the cost to deposit 1 SOL` matches the deposit branch first and can invoke `context.snapClient.deposit(pool, 1)` instead of returning an estimate. The same weakness can affect commands containing quoted, explanatory, or attacker-influenced text. The parser does not distinguish a request to discuss or estimate a deposit from authorization to execute one. ### A ...[truncated 1247 chars]
Remediation
## Remediation Suggestions - Replace substring-based intent detection with a strict, anchored command grammar or structured command schema. - Separate read-only operations such as estimates from state-changing operations before evaluating transaction intent. - Require an explicit execution form, for example `deposit <amount> SOL`, and reject commands containing estimate, quote, hypothetical, negation, or discussion language. - Parse the amount only from the expected argument position and require an explicit supported denomination. - Validate that the amount is finite, positive, within configured minimum and maximum limits, and represented without unsafe floating-point conversion. - Present the pool, amount, asset, expected fee, and wallet to the user and require explicit confirmation immediately before submission. - Prefer an unsigned transaction preview followed by a separate confirmation-bound signing operation. - Add tests for ambiguous commands, including `estimate the cost to deposit 1 SOL`, `do not deposit 1 SOL`, and quoted or explanatory text containing deposit keywords.
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (4)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The metadata description says the skill supports deposit, withdraw, list pools, and estimate fees, but the body also advertises checking a shielded/private balance. In a payments/privacy skill, undeclared balance-check behavior can imply additional wallet/viewing-key access and data handling that users or reviewers would not expect, which weakens transparency and informed consent.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill makes strong privacy claims ('Other agents and on-chain observers cannot see who you paid') but does not disclose important limits such as RPC/relayer metadata exposure, operational privacy leakage, and trust assumptions around optional third-party infrastructure. Users may overestimate anonymity and expose sensitive transaction patterns or identifiers despite believing the system is fully private.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill makes strong privacy claims ('Other agents and on-chain observers cannot see who you paid') but does not disclose important limits such as RPC/relayer metadata exposure, operational privacy leakage, and trust assumptions around optional third-party infrastructure. Users may overestimate anonymity and expose sensitive transaction patterns or identifiers despite believing the system is fully private.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill directly executes deposit and withdrawal actions based on natural-language command matching, with no explicit confirmation, preview, or approval step before moving funds. In an agent setting, ambiguous prompts, prompt injection, or accidental invocation could trigger irreversible on-chain payment actions, making this more dangerous than a typical read-only skill.

Static analysis

No suspicious patterns detected.