Back to skill

Security audit

Quack Wallet

Security checks for vulnerabilities and agentic risk

Overview

This skill matches its wallet purpose, but it can initiate token transfers with stored credentials without a confirmation step or strong local validation.

Review this skill carefully before installing. Use it only if you trust the Quack API credential and are comfortable with an agent-accessible script that can move tokens. Transfers should be treated as sensitive and potentially irreversible; require your own confirmation process and verify recipient and amount before running it.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/transfer.mjs:21
Finding
Insufficient Validation of Financial Transfer Amount## Vulnerability Details **File Location**: `scripts/transfer.mjs`, lines 21–25 and 45–50 **Vulnerability Type**: Improper input validation and unsafe numeric parsing **Risk Level**: Medium ### Vulnerable Code ```js if (!args.to || !args.amount) { console.error('Usage: node transfer.mjs --to <recipient> --amount <number> [--memo "reason"]'); process.exit(1); } ``` ```js body: JSON.stringify({ to: args.to, amount: parseFloat(args.amount), memo: args.memo, }), ``` ### Technical Analysis The transfer script verifies only that `--amount` is present. It then uses `parseFloat()` without checking whether the entire input is a valid decimal number or whether the parsed value is finite, positive, within an acceptable range, and compatible with the token's supported precision. JavaScript's `parseFloat()` accepts numeric prefixes. For example, `10abc` is silently converted to `10`. Inputs such as `0`, negative numbers, extremely large values, and values that produce non-finite results are not rejected locally. Although `JSON.stringify()` converts non-finite numeric values to `null`, the resulting malformed request is still submitted to the financial API. Correct server-side validation may prevent an invalid transaction, but the client should not rely exclusively on undocumented remote safeguards for a value-changing operation. ### Attack Path 1. A user, automation workflow, or calling Agent invokes the script with a crafted or accidentally malformed value, such as `--amount 10abc`, `--amount -10`, or an excessively large number. 2. The presence check succeeds because the argument is a non-empty string. 3. `parseFloat()` coerces the input without requiring full-string validity. 4. The resulting value is placed in the JSON request body. 5. The script sends the request to the authenticated transfer endpoint. 6. If the service accepts the coerced or insufficiently constrained value, an unint ...[truncated 855 chars]
Remediation
## Remediation Suggestions - Validate the complete amount string against the token's canonical decimal syntax rather than accepting a numeric prefix. - Convert the value once and reject it unless `Number.isFinite(amount)` is true. - Require the amount to be strictly greater than zero. - Enforce documented minimum and maximum transfer limits. - Enforce the token's supported decimal precision, preferably by converting decimal input to an integer quantity in the smallest token unit rather than relying on binary floating-point arithmetic. - Reject exponential notation unless the API explicitly supports it. - Consider requiring explicit user confirmation that displays the normalized recipient, amount, agent ID, and memo before submitting the transfer. - Preserve server-side validation as a separate mandatory control. Example hardening pattern: ```js const amountText = args.amount; if (!/^(?:0|[1-9]\d*)(?:\.\d{1,SUPPORTED_PRECISION})?$/.test(amountText)) { console.error('Amount must be a valid positive decimal with supported precision.'); process.exit(1); } const amount = Number(amountText); if (!Number.isFinite(amount) || amount <= 0 || amount > MAX_TRANSFER) { console.error('Amount is outside the permitted transfer range.'); process.exit(1); } ``` Replace `SUPPORTED_PRECISION` and `MAX_TRANSFER` with limits defined by the Quack Network API.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

Lp3

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding
The skill performs networked financial actions but declares no explicit tool scope or permission boundaries. In an agent environment, this can allow the skill to be invoked with broader-than-expected capabilities, reducing policy enforcement and making unauthorized balance checks or token transfers more likely.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The trigger phrases are broad, common expressions like 'check balance' and 'pay agent', which can cause accidental invocation during normal conversation. Because this skill can access wallet information and initiate token transfers, unintended activation could lead to privacy exposure or unauthorized financial actions.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill describes transfer commands without any warning, confirmation flow, or notice that sending tokens is a sensitive and potentially irreversible financial action. In the context of an agent fund-management skill, omission of these safeguards materially increases the chance of mistaken or socially engineered transfers.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
This script performs a live token transfer immediately after parsing CLI arguments, with no interactive confirmation, dry-run mode, recipient validation prompt, or policy gate. In the context of an agent skill explicitly designed to manage funds, that makes accidental, coerced, or prompt-injected transfers materially more likely, especially if another component can invoke the script with attacker-controlled arguments.

Missing User Warnings

Low
Confidence
78% confidence
Finding
This code performs an HTTP request to an external API and includes a Bearer token loaded from a local credentials file, but the file's visible description only says it checks agent balance and does not explicitly warn that credentials will be read and transmitted. Under the code-file criteria, network transmission of user or system data should have some user disclosure via prompt, logging, comment, or accompanying markdown warning.

Static analysis

No suspicious patterns detected.