Back to skill

Security audit

Monero Wallet

Security checks for vulnerabilities and agentic risk

Overview

This skill is a real Monero wallet controller, but it lets an agent make irreversible payments, including payments triggered by outside websites, without clear per-payment approval.

Install only if you intend to give an agent real Monero wallet authority. Use a minimally funded wallet, enforce gateway spending limits, require manual approval for every transfer or XMR402 payment, restrict paywalled requests to trusted HTTPS origins, avoid passing AGENT_API_KEY on the command line, and review or pin the external Docker setup and Python dependencies before use.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:90
Finding
Untrusted XMR402 challenges can initiate wallet payments without explicit user approval<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:90-111`; `scripts/monero_wallet_rpc.py:72-80` **Vulnerability Type**: Missing authorization controls for financial transactions **Risk Level**: High ### Vulnerable Code ```markdown If your HTTP request to an external URL returns **HTTP 402 Payment Required**, you MUST follow this exact procedure: ### Step 1: Parse the Challenge Read the `WWW-Authenticate` response header. It will contain: ```http WWW-Authenticate: XMR402 address="<subaddress>", amount="<piconero>", message="<nonce>", timestamp="<unix_ms>" ``` - **address**: Monero subaddress to pay. - **amount**: Amount in atomic units (Piconero). Divide by `1e12` for XMR. - **message**: Anti-replay nonce. Pass this EXACTLY to the `pay-402` command. ### Step 2: Pay the Invoice ```bash python3 scripts/monero_wallet_rpc.py pay-402 "<address>" <amount_in_xmr> "<message>" ``` ``` ```python def pay_402(address, amount_xmr, message, api_key=None): """XMR402 Protocol: Pay a 402 challenge and get back an Authorization header.""" res = api_call("pay_402", method="POST", data={ "address": address, "amount_xmr": float(amount_xmr), "message": message }, api_key=api_key) print(json.dumps(res)) ``` ### Technical Analysis The Skill directs the agent to pay an XMR402 challenge whenever an external HTTP service returns status 402. The destination address, amount, and nonce are controlled by that external service. Neither the instructions nor the helper require explicit user approval, validate that the payment matches an expected price, restrict eligible origins, or enforce a caller-defined transaction budget. The documented gateway spending limits reduce the maximum potential loss but do not establish that an individual payment is authorized. Duplicate-nonce checks also prevent only repeated payment of the same challenge; they do not establish the legitimacy of the initial payment. ### Attack Path 1. An agent accesse ...[truncated 892 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Require explicit, informed user approval before every XMR402 payment. - Display the origin, destination address, amount in both atomic units and XMR, and nonce before requesting approval. - Require the caller to supply a maximum expected price and reject challenges exceeding it. - Restrict automatic payment, if supported at all, to an explicit allowlist of trusted HTTPS origins. - Bind authorization to the requesting origin and exact resource so one site's challenge cannot be reused in another context. - Validate Monero address syntax, amount positivity and range, nonce format, and timestamp freshness. - Preserve gateway-side per-payment and daily limits as defense in depth rather than treating them as user authorization. - Default to refusing payment when trust, pricing, or approval information is unavailable. ]]>

T03 · Remote Payload Retrieval and Execution

Warning
Location
SKILL.md:17
Finding
Mutable external installation instructions retrieve and execute unaudited container payloads<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:17-23` **Vulnerability Type**: External mutable payload retrieval and execution **Risk Level**: Medium ### Vulnerable Code ```markdown ### 1. Install & Launch Gateway The gateway must be running locally via Docker before the skill can be used. Install and start the Ripley Gateway stack via the official instructions: - **Official Setup**: [kyc.rip/ripley](https://kyc.rip/ripley) *This will pull the necessary Docker images and start the Monero node, wallet RPC, and gateway.* ``` ### Technical Analysis The package delegates installation to instructions hosted on an external, mutable website and states that those instructions will pull and start Docker images. The audited project does not identify immutable image digests, expected registries, signatures, checksums, or the exact reviewed commands. Consequently, the effective software executed by users can change after this Skill has been reviewed. Compromise of the setup website, its delivery path, the referenced registry, or mutable image tags could substitute a different container payload. ### Attack Path 1. A user follows the external setup link as instructed by the Skill. 2. The external instructions are modified legitimately or through compromise, or a referenced mutable container tag is replaced. 3. The user runs the supplied Docker commands. 4. Docker downloads and starts payloads that were not part of this audited project. 5. The substituted container executes with the permissions, network access, mounts, devices, secrets, and wallet access granted by the setup configuration. ### Impact Assessment The precise impact depends on the external Docker configuration, which is not present in the audited project. A substituted container could obtain access to resources explicitly granted to it, potentially including wallet services, mounted files, network endpoints, and environment-provided credentials. If the external instructions request pri ...[truncated 156 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Include reviewed installation instructions directly in the repository. - Identify every required image using an immutable digest rather than a mutable tag. - Document the expected registry and repository for each image. - Require signature verification, such as Sigstore/Cosign verification, before execution. - Publish and verify checksums or attestations for installation artifacts. - Pin the Docker Compose file and all referenced artifacts to reviewed revisions. - Use least-privilege container settings: no privileged mode, no Docker socket mount, read-only filesystems where possible, dropped Linux capabilities, restricted networks, and narrowly scoped volume mounts. - Document an update procedure that requires a new security review whenever image digests or setup scripts change. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/monero_wallet_rpc.py:87
Finding
Gateway API key can be exposed through command-line arguments<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:43-47`; `scripts/monero_wallet_rpc.py:87` **Vulnerability Type**: Sensitive credential exposure through process arguments and shell history **Risk Level**: Medium ### Vulnerable Code ```markdown The preferred way to interact with the wallet is via the included `monero_wallet_rpc.py` script. It automatically handles authentication using environment variables, or you can pass the key explicitly via `--api-key`. ### 1. Check Sync Status ```bash python3 scripts/monero_wallet_rpc.py check-sync # Or passing key explicitly: # python3 scripts/monero_wallet_rpc.py --api-key YOUR_KEY check-sync ``` ``` ```python parser.add_argument("--api-key", help="Ripley Gateway API Key (defaults to AGENT_API_KEY env)") ``` ### Technical Analysis Accepting a secret through `--api-key` places it in the process argument vector. Depending on operating-system configuration, process arguments may be visible to other local users or monitoring software. The literal command can also be retained in shell history, terminal logs, audit records, orchestration metadata, crash reports, or agent execution telemetry. The key authorizes requests to the local wallet gateway. Hardcoding the gateway URL to localhost prevents direct transmission to a remote host but does not protect a key disclosed through local process metadata. ### Attack Path 1. A user or agent follows the documented example and passes the gateway key through `--api-key`. 2. The complete command is stored in shell history, captured by telemetry, or exposed through process inspection while running. 3. A local user, service, or log reader obtains the key. 4. The actor sends authenticated requests to `http://127.0.0.1:38084`. 5. Subject to gateway policy, the actor queries wallet information or initiates wallet operations, including transfers. ### Impact Assessment An exposed key may grant the same gateway permissions assigned to the legitimate agent. Depending on g ...[truncated 317 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove the `--api-key` command-line option and its documentation. - Prefer a protected credential source, such as a permission-restricted configuration file, operating-system key store, secret manager, or inherited file descriptor. - If environment variables remain supported, ensure the execution platform does not log or expose the environment and document that limitation. - Redact API keys from command telemetry, audit logs, exceptions, and diagnostic output. - Rotate the gateway key if it has previously been supplied on a command line. - Scope gateway credentials to the minimum necessary operations and enforce short lifetimes where supported. - Retain localhost-only gateway binding and enforce gateway-side transaction limits as additional controls. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/monero_wallet_rpc.py:8
Finding
Python dependency is installed without version or integrity pinning<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:5`; `scripts/monero_wallet_rpc.py:8-13` **Vulnerability Type**: Unpinned third-party dependency **Risk Level**: Medium ### Vulnerable Code ```yaml metadata: {"openclaw": {"emoji": "💰", "homepage": "https://github.com/KYC-rip/ripley-xmr-gateway", "category": "finance", "requires": {"bins": ["python3", "curl"], "env": ["AGENT_API_KEY"], "pip": ["requests"]}, "primaryEnv": "AGENT_API_KEY"}} ``` ```python try: import requests except ImportError: print("Error: The 'requests' library is missing.", file=sys.stderr) print("Please install it via: pip install requests", file=sys.stderr) sys.exit(1) ``` ### Technical Analysis The project declares and recommends installation of `requests` without a fixed version, lockfile, package hash, or provenance verification. Installation behavior therefore depends on the package version served by the configured Python package index at installation time. This makes builds non-reproducible and allows an unexpectedly incompatible or compromised future upstream release to enter the Skill environment without a corresponding project review. The package name itself is the legitimate `requests` name, so there is no evidence of typosquatting or dependency confusion in the current files; the confirmed issue is the absence of pinning and integrity controls. ### Attack Path 1. The runtime does not already contain the `requests` package. 2. The user follows the instruction to run `pip install requests`, or the Skill manager installs the unpinned declared dependency. 3. The package index supplies the latest version available at that time. 4. If that release or the configured index has been compromised, its installation or runtime code executes in the Skill's Python environment. 5. Malicious dependency code can act with the Python process's permissions and potentially access environment variables such as `AGENT_API_KEY`. ### Impact Assessment A compromised dep ...[truncated 380 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Pin `requests` and its transitive dependencies to reviewed versions in a lockfile. - Record and enforce cryptographic hashes for every installed distribution. - Install with hash verification, for example through a fully hashed requirements file and `pip --require-hashes`. - Use a trusted, explicitly configured package index and disable unintended fallback indexes. - Generate a software bill of materials and scan pinned dependencies for known vulnerabilities. - Review and deliberately update dependency pins on a controlled schedule. - Build in an isolated environment and avoid running package installation with elevated privileges. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The description presents the skill as a wallet-management interface, but the body also introduces an XMR402 payment flow that can cause the agent to pay third-party services and interact with arbitrary external URLs. That hidden behavioral expansion is dangerous because reviewers may approve a local-wallet skill without realizing it authorizes spending in response to external 402 challenges.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill declares capabilities that involve environment-variable access and network activity, but it does not define an explicit tool scope such as permissions or allowed-tools. In an agent setting, that omission weakens policy enforcement and can let the skill be invoked with broader runtime powers than reviewers or users expect, especially given that it can initiate wallet actions and outbound HTTP requests.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill documents irreversible transfer and payment actions without requiring an explicit confirmation or approval step before spending wallet funds. In an autonomous agent context, that can turn prompt injection, user misunderstanding, or malicious third-party content into immediate irreversible financial loss.

External Transmission

Medium
Category
Data Exfiltration
Content
Example:
```bash
curl -H "X-API-KEY: $AGENT_API_KEY" http://127.0.0.1:38084/sync
```

## XMR402 Payment Gating (v1.0.1)
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
Although the skill is framed as using a secure local gateway, it instructs the agent to make arbitrary requests to external paywalled URLs and then spend Monero based on unauthenticated challenge data from those sites. This creates a direct path for untrusted external services to induce wallet payments, potentially draining funds or causing repeated micropayments to attacker-controlled endpoints.

External Transmission

Medium
Category
Data Exfiltration
Content
### Example Flow
```bash
# 1. Attempt access (returns 402)
curl -i https://api.example.com/protected
# => 402, WWW-Authenticate: XMR402 address="5...", amount="10000000000", message="abc123..."

# 2. Check if already paid for this nonce
Confidence
88% confidence
Finding
The skill explicitly directs requests to arbitrary external URLs as part of the payment-gating flow. This increases exposure to malicious services that can fabricate or manipulate 402 challenges to trigger unnecessary payments or influence subsequent agent behavior.

External Transmission

Medium
Category
Data Exfiltration
Content
http://127.0.0.1:38084/get_proof

# 3. Retry with proof
curl -H 'Authorization: XMR402 txid="...", proof="..."' https://api.example.com/protected
# => 200 OK
```
Confidence
90% confidence
Finding
Retrying external requests with an authorization header containing payment proof sends transaction-linked metadata to third-party endpoints. While expected for XMR402, it still expands the trust boundary and can leak payment correlation data or enable abuse when interacting with untrusted services.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The security comment is misleading: sending the API key over plain HTTP to 127.0.0.1 does not guarantee safety, because any local process able to bind or proxy that port can receive the credential. In an agent runtime, localhost services are part of the attack surface, so a malicious or compromised local process could capture the API key and abuse wallet operations.

Description-Behavior Mismatch

Medium
Confidence
90% confidence
Finding
The skill includes a pay_402 operation that can initiate Monero payments for challenge-response authorization, which expands behavior beyond straightforward wallet management described in the manifest. In an agent context, hidden or under-disclosed payment capabilities are dangerous because they can be invoked to transfer funds in response to untrusted remote prompts or protocol challenges, increasing the chance of unintended spending.

Intent-Code Divergence

Low
Confidence
87% confidence
Finding
Line L012 states the skill interacts with a wallet through a secure local gateway, suggesting a local-only operational model. Later lines L086-L155 instruct the agent to access external URLs, parse payment challenges from them, and resend authenticated requests, which contradicts that local-only framing rather than merely omitting detail.

Static analysis

No suspicious patterns detected.