Back to skill

Security audit

Routstr Skill

Security checks for vulnerabilities and agentic risk

Overview

This skill is mostly aligned with Routstr balance management, but it handles financial credentials and payment tokens in unsafe and under-scoped ways.

Review before installing. Use only on a trusted machine, with a Routstr API key you are comfortable exposing to these scripts, and avoid using Cashu tokens with this version because the token is placed in a URL where it may be logged or visible in process metadata. The invoice script should be fixed to validate amounts and align units before relying on it for payments.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
create_invoice.sh:6
Finding
Unvalidated Input Evaluated as a Bash Arithmetic Expression<![CDATA[ ## Vulnerability Details **File Location**: `create_invoice.sh`, lines 6-14 **Vulnerability Type**: Shell command injection through unsafe arithmetic evaluation **Risk Level**: High ### Vulnerable Code ```bash # Check amount argument if [ -z "$1" ]; then echo "Usage: $0 <amount_sats>" echo "Example: $0 1000" exit 1 fi # Convert sats to msats (API expects msats) AMOUNT_SATS="$1" AMOUNT_MSATS=$((AMOUNT_SATS * 1000)) ``` ### Technical Analysis The script only verifies that the first argument is nonempty. It does not ensure that the value is a decimal integer before using it in Bash arithmetic expansion. Bash arithmetic expressions can recursively interpret variable values as arithmetic syntax. Crafted values may introduce variable references, array subscripts, or command substitutions in arithmetic contexts. Consequently, treating untrusted input as an arithmetic expression can result in unintended command execution rather than a simple numeric conversion. The vulnerable expression executes with the privileges and environment of the user running the Skill. ### Attack Path 1. An attacker supplies or persuades the user or agent to supply a specially crafted invoice amount. 2. The value is copied unchanged into `AMOUNT_SATS`. 3. The script evaluates `AMOUNT_SATS` inside `$((...))`. 4. Bash interprets the crafted value as arithmetic syntax and may evaluate embedded expansion constructs. 5. Attacker-controlled commands execute under the account that invoked the script. ### Impact Assessment Successful exploitation may provide arbitrary command execution with the privileges of the current Skill user. This could permit access to files readable by that account, including `~/.openclaw/openclaw.json` and its Routstr API key, modification of user-owned data, execution of network requests, or installation of user-level persistence. The issue does not directly grant root privileges unless the script is separately invoked through a privileged executio ...[truncated 16 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Validate the argument before any arithmetic operation and enforce a reasonable business limit: ```bash AMOUNT_SATS="${1:-}" if [[ ! "$AMOUNT_SATS" =~ ^[0-9]+$ ]]; then echo "Error: amount_sats must be a positive decimal integer." >&2 exit 1 fi if (( 10#$AMOUNT_SATS == 0 || 10#$AMOUNT_SATS > 100000000 )); then echo "Error: amount_sats is outside the permitted range." >&2 exit 1 fi AMOUNT_MSATS=$((10#$AMOUNT_SATS * 1000)) ``` The `10#` prefix forces base-10 interpretation after validation. The maximum value should be selected according to the service's documented limits and should also prevent integer overflow. Add tests covering empty, negative, hexadecimal, oversized, malformed, and expression-like inputs. Consider enabling strict shell behavior with `set -euo pipefail`, while explicitly handling expected command failures. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
topup_cashu.sh:19
Finding
Cashu Bearer Token Exposed in Request URL and Process Arguments<![CDATA[ ## Vulnerability Details **File Location**: `topup_cashu.sh`, lines 19-21 **Vulnerability Type**: Sensitive bearer token disclosure through a URL query parameter **Risk Level**: High ### Vulnerable Code ```bash # Make topup request (cashu token in query params, not body) echo "Topping up with Cashu token..." RESPONSE=$(curl -s -X POST "${BASE_URL}/wallet/topup?cashu_token=$(echo "${CASHU_TOKEN}" | jq -sRr @uri)" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${API_KEY}") ``` ### Technical Analysis A Cashu token represents bearer-value financial material: possession may be sufficient to redeem its value. The script places the complete token in the URL query string passed to `curl`. URL query strings are commonly exposed through local process inspection, shell or execution telemetry, HTTP server access logs, reverse proxies, monitoring systems, tracing platforms, error reports, and request histories. URL encoding only makes the token syntactically safe for transport; it does not encrypt or redact it. Although HTTPS protects the URL while it is transmitted over the network, it does not prevent disclosure through local process metadata or endpoint, proxy, and server-side logging. ### Attack Path 1. A user invokes `topup_cashu.sh` with a valuable Cashu token. 2. The script URL-encodes the token and inserts it into the request URL. 3. The complete URL is supplied as a command-line argument to `curl`. 4. A local observer, process-monitoring product, request logger, reverse proxy, or server access log captures the URL. 5. An attacker extracts and decodes the token. 6. The attacker attempts to redeem the bearer token before or instead of the intended top-up operation. ### Impact Assessment Disclosure may allow theft or unauthorized redemption of the monetary value represented by the Cashu token. Exposure is potentially available to users or monitoring agents capable of viewing process metadata and to administrators or systems wi ...[truncated 230 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Do not place bearer tokens in URLs. Change the API integration to submit the token in a POST body or a protected request header. Prefer feeding the body to `curl` through standard input so the secret is not included directly in process arguments. For example, if supported by the API: ```bash PAYLOAD=$(jq -n --arg cashu_token "$CASHU_TOKEN" \ '{"cashu_token": $cashu_token}') RESPONSE=$(printf '%s' "$PAYLOAD" | curl --silent --show-error --fail-with-body \ -X POST "${BASE_URL}/wallet/topup" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${API_KEY}" \ --data-binary @-) ``` Additionally: - Configure application servers, proxies, and observability tools to redact Cashu tokens and authorization headers. - Require HTTPS and validate the destination host before sending either secret. - Avoid debug modes such as `set -x` while handling tokens. - Minimize token lifetime and redeem submitted tokens atomically where supported. - Review and purge existing logs that may contain historical token-bearing URLs. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
topup_cashu.sh:6
Finding
Complete Cashu Token-Like Bearer Payload Embedded in Usage Output<![CDATA[ ## Vulnerability Details **File Location**: `topup_cashu.sh`, lines 6-10 **Vulnerability Type**: Hardcoded financial bearer-token material **Risk Level**: Medium ### Vulnerable Code ```bash # Check cashu token argument if [ -z "$1" ]; then echo "Usage: $0 <cashu_token>" echo "Example: $0 cashuBo2FteCJodHRwczovL21pbnQubWluaWJpdHMuY2FzaC9CaXRjb2luYXVjc2F0YXSBomFpSAAQeTfbDMhlYXCBo2FhAWFzeEBkNWJjNWYxYmE2YmJlNDQ2NGM3YmI1NjQ4MzBhNWY1ZDRjZDU3ZjJhOTQ3ZGQwYmE0ZjJmYjgwZTNlMmI4NmNhYWNYIQObVC-sFR3tVKwD08eDbJGrvP6J_IZ7k6k2Yn4CjY5Bog" exit 1 fi ``` ### Technical Analysis The help text contains a complete value with the structure and prefix of a Cashu token rather than a short, unmistakably invalid placeholder. Cashu tokens are bearer instruments and must be handled as secrets because possession may permit redemption. Static analysis cannot establish whether this particular token remains valid, has already been redeemed, or was generated solely as test data. Nevertheless, embedding a complete token-like payload in distributed source code creates an avoidable secret-exposure and accidental-redemption risk. It also encourages users to copy or reuse realistic financial credentials in documentation and command histories. ### Attack Path 1. An attacker obtains the publicly distributed or locally installed Skill package. 2. The attacker reads `topup_cashu.sh` and extracts the embedded token-like value. 3. The attacker submits the value to a compatible Cashu wallet or mint. 4. If the token is valid and unspent, the attacker may redeem or transfer its value. The final redemption step depends on the token still being valid and unspent; that condition cannot be confirmed from the audited source alone. ### Impact Assessment If the embedded value is valid and unspent, its monetary value may be stolen by anyone with access to the source package. If it is invalid or already redeemed, there is no direct financial loss, but retaining realistic bearer material still c ...[truncated 108 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Replace the complete token-like value with a short placeholder that cannot be mistaken for a redeemable token: ```bash if [ -z "${1:-}" ]; then echo "Usage: $0 <cashu_token>" echo "Example: $0 '<CASHU_TOKEN>'" exit 1 fi ``` Determine whether the embedded value was ever valid. If so, treat it as compromised, verify its redemption status, rotate or invalidate related test material where possible, and inspect repository history and published artifacts for copies. Add secret scanning rules capable of detecting Cashu token prefixes and prohibit genuine bearer tokens in source code, examples, tests, and documentation. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • 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 (11)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The documentation introduces or implies financially sensitive actions such as Cashu-based top-ups without clearly reconciling them with the declared purpose. In a payment-related skill, incomplete or inconsistent disclosure is risky because it can cause users to trigger money-moving actions they did not expect from the stated scope.

Tp4

High
Category
MCP Tool Poisoning
Confidence
88% confidence
Finding
The documentation introduces or implies financially sensitive actions such as Cashu-based top-ups without clearly reconciling them with the declared purpose. In a payment-related skill, incomplete or inconsistent disclosure is risky because it can cause users to trigger money-moving actions they did not expect from the stated scope.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The documentation introduces or implies financially sensitive actions such as Cashu-based top-ups without clearly reconciling them with the declared purpose. In a payment-related skill, incomplete or inconsistent disclosure is risky because it can cause users to trigger money-moving actions they did not expect from the stated scope.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill advertises shell and network-capable operations but declares no explicit tool scope or permissions. That creates an authorization gap where an agent or user may invoke a capability set broader than what is transparently documented, increasing the chance of unintended network access or command execution.

Session Persistence

Medium
Category
Rogue Agent
Content
## What I do
- Check current Routstr API balance (in sats and BTC)
- Display usage statistics (total spent, total requests)
- Create Lightning invoices for top-up payments
- Check payment status of existing invoices
- Top up balance using Cashu tokens
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The script extracts a credential from ~/.openclaw/openclaw.json and transmits it via curl as a Bearer token. Although comments describe the mechanics, there is no user-facing disclosure, prompt, or warning in the script about credential use or the outbound network request.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The script converts the user-supplied amount from sats to millisats, but then places that converted value into a JSON field named `amount_sats`. If the server interprets that field literally as sats, the created invoice could be 1000x larger than intended, causing accidental overpayment requests or operational loss.

External Transmission

Medium
Category
Data Exfiltration
Content
# Create invoice (note: API expects amount in msats)
echo "Creating $AMOUNT_SATS sat invoice..."
RESPONSE=$(curl -s -X POST "${BASE_URL}/balance/lightning/invoice" \
  -H "Content-Type: application/json" \
  -d "{\"amount_sats\": ${AMOUNT_MSATS}, \"purpose\": \"topup\", \"api_key\": \"${API_KEY}\"}")
Confidence
91% confidence
Finding
The script transmits the Routstr API key inside the JSON request body during an external `curl` call. Sending credentials in the body rather than a standard authorization header increases exposure through logs, proxies, debugging output, and server-side request recording, and the skill context is balance management so credential misuse could directly affect funds-related operations.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The manifest says the skill manages balance by checking balance, creating Lightning invoices for top-up, and checking invoice payment status. This script instead performs a direct wallet top-up using a Cashu token via /wallet/topup, which is a distinct funding mechanism not mentioned in the manifest description.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The Cashu token is placed in the request URL query string, which can be exposed through shell history, process listings, proxy logs, web server access logs, monitoring tools, and error telemetry. Because the token is a bearer-like value representing spendable value, disclosure can enable theft or replay by anyone who obtains logged URLs.

Missing User Warnings

Low
Confidence
93% confidence
Finding
The skill explicitly states that it reads configuration from a local file but does not warn that this file may contain sensitive API credentials. Users may run the skill without understanding that local secrets are being accessed, increasing the risk of accidental disclosure, misuse, or execution in inappropriate environments.

Static analysis

No suspicious patterns detected.