Back to skill

Security audit

AAWP — AI Agent Wallet Protocol

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real AI-wallet skill, but its installer and runtime setup are too powerful and mutable for a user to trust without careful review.

Treat this as Review before install. Do not use it with real assets unless you can audit and pin the remote GitHub runtime, verify every downloaded file before execution, install only into the client you intend, and set strict limits for automated trading or contract calls. Test in an isolated environment with a low-value wallet first.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T01 · Skill Instruction Hijacking

Error
Location
package.json:8
Finding
Automatic Installation of a Mutable Remote Skill Manifest<![CDATA[ ## Vulnerability Details **File Location**: `package.json:8`; `bin/install.js:8-9, 14-18, 60-77, 126-131, 143-204` **Vulnerability Type**: Remote instruction retrieval and persistent Skill installation **Risk Level**: Critical ### Vulnerable Code ```json "scripts": { "postinstall": "node bin/install.js" } ``` ```js const RAW_BASE = 'https://raw.githubusercontent.com/aawp-ai/aawp/main/skills/aawp'; const FALLBACK = 'https://aawp.ai/skill'; function validateSkillMd(content, sourceUrl) { // Must be a valid SKILL.md with expected markers if (!content.startsWith('---')) throw new Error('Downloaded content is not a valid SKILL.md (missing YAML frontmatter)'); if (!content.includes('name: aawp')) throw new Error('Downloaded SKILL.md does not match expected skill identity'); if (!content.includes('aawp.ai')) throw new Error('Downloaded SKILL.md failed content integrity check'); return true; } async function downloadSkillMd() { const primaryUrl = `${RAW_BASE}/SKILL.md`; const fallbackUrl = `${FALLBACK}/SKILL.md`; let content, sourceUrl; try { content = await fetchText(primaryUrl); sourceUrl = primaryUrl; } catch { content = await fetchText(fallbackUrl); sourceUrl = fallbackUrl; } info(`Source: ${dim(sourceUrl)}`); validateSkillMd(content, sourceUrl); return content; } function installToDir(baseDir, skillMd) { const dest = path.join(baseDir, SKILL_NAME); fs.mkdirSync(dest, { recursive: true }); fs.writeFileSync(path.join(dest, 'SKILL.md'), skillMd, 'utf8'); return dest; } ``` ### Technical Analysis The npm `postinstall` lifecycle hook automatically runs the installer. Rather than installing the reviewed, bundled `SKILL.md`, the installer downloads a new manifest from either the mutable GitHub `main` branch or an independently controlled website. The downloaded manifest is authenticated only by checking for three ordinary text markers. These checks do not establish integrity or publisher authent ...[truncated 2287 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove all network retrieval from the npm `postinstall` lifecycle. 2. Install the reviewed `SKILL.md` bundled inside the published package. 3. Do not modify AI-client directories automatically during dependency installation; require an explicit installer command and informed user confirmation. 4. If remote manifest retrieval is unavoidable: - Pin an immutable release commit or content-addressed artifact; - Embed the expected SHA-256 digest in the npm package; - Verify a digital signature against a public key bundled through a separate trust channel; - Reject redirects and unexpected origins; - Fail closed when verification cannot be completed. 5. Display the destination and verified artifact identity before writing any file. 6. Provide a dry-run mode and request confirmation separately for every client destination. 7. Treat changes to the manifest as new reviewed releases rather than silently serving them from a mutable branch. ]]>

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:65
Finding
Unpinned Provisioning of Native Signing Code and Wallet Runtime<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:65-69, 138-141`; `package.json:3, 26`; `README.md:67-86` **Vulnerability Type**: Unverified remote native-code and script provisioning **Risk Level**: Critical ### Vulnerable Code ```markdown > **📦 Installer-Only Package** > The ClawHub/npm package (`aawp-skill`) contains only this manifest (SKILL.md), README, and a small `bin/install.js` bootstrap. > The full runtime stack — native signing addon (`core/aawp-core.node`), wallet scripts (`scripts/*.js`), and daemon — is fetched from [github.com/aawp-ai/aawp](https://github.com/aawp-ai/aawp) during `bash scripts/provision.sh`. > The native binary hash is verified on-chain via the AAWP factory (`approveBinary(hash)`) before any wallet operation is permitted. ``` ```markdown # Git (OpenClaw / full daemon + all scripts) git clone https://github.com/aawp-ai/aawp.git ~/.agents/skills/aawp ``` ```markdown # 1. Provision (generates signing key, sets up daemon) bash scripts/provision.sh ``` ```json "note": "This package is an installer manifest only. The native binary (aawp-core.node), wallet scripts, and provisioning tools are downloaded from https://github.com/aawp-ai/aawp at runtime via 'bash scripts/provision.sh'. The native binary hash is verified on-chain via the AAWP factory contract before any wallet operations." ``` ### Technical Analysis The package does not include the runtime components responsible for private-key handling and transaction signing. Instead, users are directed to clone the mutable default branch of a GitHub repository and execute its `scripts/provision.sh` script. That provisioning flow is expected to supply: - A precompiled native Node.js addon; - Wallet-management scripts; - A persistent signing daemon; - Key-provisioning tools; and - Automation scripts capable of registering scheduled financial operations. No release tag, immutable commit, signed manifest, or trusted pre-execution checksum is specified. The runtime th ...[truncated 2551 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Publish the complete auditable runtime with the package or as a separately versioned, signed artifact. 2. Pin installation to an immutable Git commit and release tag rather than the repository’s default branch. 3. Publish a signed artifact manifest containing hashes for every script, native addon, daemon file, and configuration template. 4. Bundle the trusted verification key and expected manifest identity in the reviewed installer. 5. Verify every downloaded file before any script is sourced, loaded, or executed. 6. Do not let the downloaded provisioning script verify itself or define its own expected hash. 7. Use reproducible builds for `aawp-core.node` and publish build instructions, source commit identifiers, compiler versions, and provenance attestations. 8. Require explicit human approval before: - Downloading native code; - Executing provisioning; - Generating wallet authority; - Starting a daemon; or - Registering scheduled transactions. 9. Run provisioning with restricted filesystem and network access where feasible. 10. Audit the complete remote repository, native addon, daemon, smart contracts, and provisioning path before entrusting it with assets. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
bin/install.js:92
Finding
Postinstall Writes the Skill into Multiple Unrelated AI-Client Directories<![CDATA[ ## Vulnerability Details **File Location**: `bin/install.js:92-122, 143-204`; `package.json:8` **Vulnerability Type**: Excessive installation scope and cross-client persistence **Risk Level**: High ### Vulnerable Code ```js const CLIENTS = [ { name: 'OpenClaw', detect: () => hasCmd('clawhub'), install: async () => { const r = spawnSync('clawhub', ['install', SKILL_NAME], { stdio: 'inherit' }); return r.status === 0; }, skillDir: null, }, { name: 'Cursor', detect: () => hasCmd('cursor') || dirExists(path.join(HOME, '.cursor')), skillDir: path.join(HOME, '.cursor', 'skills'), }, { name: 'Claude Code', detect: () => hasCmd('claude') || dirExists(path.join(HOME, '.claude')), skillDir: path.join(HOME, '.claude', 'skills'), }, { name: 'Gemini CLI', detect: () => hasCmd('gemini') || dirExists(path.join(HOME, '.gemini')), skillDir: path.join(HOME, '.gemini', 'skills'), }, { name: 'OpenCode', detect: () => hasCmd('opencode') || dirExists(path.join(HOME, '.config', 'opencode')), skillDir: path.join(HOME, '.config', 'opencode', 'skills'), }, { name: 'Goose', detect: () => hasCmd('goose') || dirExists(path.join(HOME, '.config', 'goose')), skillDir: path.join(HOME, '.config', 'goose', 'skills'), }, ]; const UNIVERSAL_DIR = path.join(HOME, '.agents', 'skills'); ``` ```js const detected = CLIENTS.filter(c => c.detect()); const seenDirs = new Set(); const dirsToInstall = []; for (const client of detected) { if (client.skillDir && !seenDirs.has(client.skillDir)) { seenDirs.add(client.skillDir); dirsToInstall.push({ dir: client.skillDir, label: client.name }); } } if (!seenDirs.has(UNIVERSAL_DIR)) { dirsToInstall.push({ dir: UNIVERSAL_DIR, label: 'universal (~/.agents/skills)' }); } for (const { dir, label } of dirsToInstall) { const shortDir = dir.replace(HOME, '~'); info(`Installing to ${shortDir}/aawp/ ${dim('(' + label + ')' ...[truncated 2353 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove installation behavior from the npm `postinstall` hook. 2. Require the user to run an explicit installation command. 3. Require a target option such as `--client claude` or `--destination PATH`. 4. Default to installing nowhere when no target is specified. 5. Display the exact destination, source artifact, version, and digest before installation. 6. Obtain separate confirmation before modifying each client directory. 7. Do not install into the universal directory unless explicitly requested. 8. Avoid invoking `clawhub install` as a side effect of another package’s lifecycle hook. 9. Provide an uninstall command that removes only files created by the installer and reports all affected destinations. 10. Record an installation manifest so users can audit and reverse cross-client changes. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (13)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill is presented as a wallet protocol, but the document states that installation fetches the full runtime stack from GitHub during provisioning and static analysis indicates additional local file modification, environment detection, and installer delegation behaviors. This mismatch is dangerous because operators may trust the manifest while the actual executed code path introduces a remote supply-chain and post-install behavior surface not fully disclosed or pinned in the manifest itself.

Ae1

High
Category
analysis-evasion
Content
> The ClawHub/npm package (`aawp-skill`) contains only this manifest (SKILL.md), README, and a small `bin/install.js` bootstrap.
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding
The README instructs users to execute `npx aawp-ai` without pinning a version or integrity-protecting the package. In a wallet skill that provisions signing material and can move on-chain assets, this creates a serious supply-chain risk: a compromised or newly published package version could execute arbitrary code, exfiltrate keys, or trigger unauthorized transactions at install/run time.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The README promotes autonomous DCA strategies, price alerts, and scheduled transactions via a persistent daemon, but it does not place a clear safety warning adjacent to that behavior. In the context of an AI-controlled wallet, autonomous execution materially increases the chance of unintended asset movement, repeated losses, or abuse if the daemon, configuration, or trigger logic is misconfigured or compromised.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The documented `--auto-swap` price alert can automatically trade when market conditions are met, yet the README does not clearly warn that this will execute real transactions and move assets automatically. Because this skill is specifically a crypto wallet protocol with swap, bridge, and contract-call capabilities, users may underestimate the operational and financial risk of enabling trigger-based trading.

Lp3

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding
The manifest documents extensive network-dependent behavior but does not declare any tool scope or allowed-tools boundary. In a wallet skill that can fetch remote components, query chains, and submit transactions, missing explicit permission scoping increases the chance that an agent runtime grants broader network access than operators expect.

Intent-Code Divergence

Medium
Confidence
91% confidence
Finding
The document says provisioning, wallet creation, cron registration, and binary approval require human confirmation, but later sections provide direct execution steps for the same sensitive actions as routine commands. In an autonomous-agent context, contradictory guidance can cause dangerous operations like key generation, wallet deployment, or recurring on-chain execution to be treated as normal automation instead of high-risk actions.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The documented capabilities expand beyond the high-level description to include NFT operations, lending/borrowing, and token launch/deployment. In a wallet skill, undocumented expansion of financial and contract-deployment powers materially increases risk because users may approve the skill for transfers/swaps without realizing it can also mint, borrow, approve operators, or deploy tokens/contracts.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The package presents itself as an installer-only manifest, yet it also defines a postinstall hook that executes code automatically during npm install. In this skill’s context, that installer is explicitly intended to fetch runtime files and provisioning tooling later, so installation-time execution creates a supply-chain attack surface before the user can meaningfully review or consent to wallet-related setup behavior.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The manifest states that runtime components are downloaded from GitHub and provisioned via a bash script, but the package-level install path already auto-runs installer logic through postinstall. That combination is dangerous because it couples package installation with network retrieval and shell-based provisioning, enabling remote code execution and dependency confusion or repository compromise scenarios with limited user awareness.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The manifest says a Guardian private key will be auto-generated if not provided, without showing a clear opt-in or describing storage, export, encryption, and recovery guarantees. In a crypto wallet skill, silent key creation is especially sensitive because users or agents may unknowingly rely on a newly created credential that can control funds or relaying behavior, increasing the risk of loss, misuse, or insecure secret handling.

Description-Behavior Mismatch

Low
Confidence
94% confidence
Finding
The skill is described like a packaged wallet capability, but the document reveals it is only an installer/bootstrap that downloads the actual runtime stack later. That distinction is security-significant because review of the shipped manifest is not equivalent to review of the code that will ultimately run, creating a classic remote payload/supply-chain trust gap.

Natural-Language Policy Violations

Low
Confidence
81% confidence
Finding
The natural-language description repeatedly states 'Not for humans' and frames the skill as exclusively for AI agents, which is an organizational-use restriction expressed in prose rather than a technical constraint or user choice. Under this audit's policy-focused category, prescriptive language that forces a usage constraint without opt-in or documented justification can be flagged as a natural-language policy issue.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
bin/install.js:80