Back to skill

Security audit

Relay Link Bridge

Security checks for vulnerabilities and agentic risk

Overview

This skill is a real bridge automation tool, but it can sign and broadcast wallet transactions with a local private key while giving users too little transaction detail to verify what they are approving.

Review this carefully before installing. Use only a dedicated low-balance wallet, assume any confirmed bridge action can move real funds irreversibly, and do not use it until transaction details, RPC chain checks, spender/approval limits, and private-key handling are made much stricter.

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

Error
Location
scripts/quick-bridge.sh:135
Finding
Unvalidated Remote Transaction Payload Is Signed with the User's Private Key<![CDATA[ ## Vulnerability Details **File Location**: `scripts/quick-bridge.sh`, lines 135–149 and 174–183 **Vulnerability Type**: Unvalidated signing of remotely supplied blockchain transaction data **Risk Level**: High ### Vulnerable Code ```bash CONVERTED_AMOUNT=$(echo "$AMOUNT * 10^18" | bc | cut -d'.' -f1) QUOTE=$(curl -s -X POST "https://api.relay.link/quote/v2" \ -H "Content-Type: application/json" \ -d "{ \"user\": \"$USER_ADDR\", \"originChainId\": $ORIGIN_ID, \"destinationChainId\": $DEST_ID, \"originCurrency\": \"$ORIGIN_CURR\", \"destinationCurrency\": \"$DEST_CURR\", \"recipient\": \"$DEST_ADDR\", \"amount\": \"$CONVERTED_AMOUNT\", \"tradeType\": \"EXACT_INPUT\" }") ``` ```bash read -p "Do you want to sign and send this transaction now? (yes/no): " CONFIRM if [ "$CONFIRM" == "yes" ]; then echo "🚀 Sending transaction..." TX_TO=$(echo "$QUOTE" | jq -r '.steps[0].items[0].data.to') TX_VALUE=$(echo "$QUOTE" | jq -r '.steps[0].items[0].data.value') TX_DATA=$(echo "$QUOTE" | jq -r '.steps[0].items[0].data.data') # Use environment variable for private key instead of CLI arg for security export ETH_PRIVATE_KEY="$EVM_PRIVATE_KEY" RESULT=$(cast send "$TX_TO" "$TX_DATA" --value "$TX_VALUE" --rpc-url "$RPC_URL_AVAX" 2>&1) ``` The RPC endpoint is also fixed to Avalanche regardless of the selected origin chain: ```bash RPC_URL_AVAX="https://api.avax.network/ext/bc/C/rpc" ``` ### Technical Analysis The script treats the Relay quote API response as trusted transaction authorization data. The remote response directly controls: - The transaction recipient through `.data.to` - The native currency amount through `.data.value` - The contract call and its arguments through `.data.data` These values are passed directly to `cast send`, which signs the transaction using the private key loaded from `EVM_PRIVATE_KEY`. The script does not validate the destinati ...[truncated 3013 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Verify the active chain before signing** - Map each supported origin chain to an approved RPC endpoint. - Query the RPC chain ID immediately before signing. - Abort unless it exactly matches `originChainId`. - Do not silently route every transaction through Avalanche. 2. **Validate every transaction field** - Require `to`, `value`, and `data` to exist and have valid formats. - Reject `null`, empty, malformed, or unexpected fields. - Enforce a maximum native value derived from the user's requested amount and an explicit fee allowance. - Maintain an allowlist of official bridge/router contracts for each chain. - Reject transaction targets that are not approved for the selected route. 3. **Decode and constrain calldata** - Decode the function selector and arguments before signing. - Permit only expected bridge, transfer, and approval methods. - For token approvals, verify the spender and cap the approval to the amount required for the current transaction. - Reject unlimited approvals unless separately and explicitly authorized. 4. **Provide meaningful confirmation** - Display the origin chain and verified RPC chain ID. - Display the target contract, native value, decoded operation, token amount, spender, approval amount, fees, slippage, and recipient. - Require confirmation only after all fields that will be signed have been shown. - Ensure that the transaction fields displayed are the exact immutable fields subsequently passed to `cast send`. 5. **Handle token precision correctly** - Obtain token decimals from trusted chain metadata or an on-chain contract query. - Validate that the requested currency belongs to the selected origin chain. - Convert the human-readable amount using the verified token precision instead of always using 18 decimals. 6. **Fail closed** - Enable strict shell behavior such as `set -euo pipefail`. - Use `curl --fail --show-error` w ...[truncated 500 chars]
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (18)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
This finding points to materially risky behavior in the wider skill design: use of EVM_PRIVATE_KEY from local config and direct transaction signing/broadcasting are highly sensitive capabilities, yet the skill description and permission model do not clearly communicate or constrain that risk. In a bridge/swap context, hidden signing logic or chain-specific RPC assumptions can lead to unauthorized transfers, signing on the wrong network, or silent fund loss.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
This finding points to materially risky behavior in the wider skill design: use of EVM_PRIVATE_KEY from local config and direct transaction signing/broadcasting are highly sensitive capabilities, yet the skill description and permission model do not clearly communicate or constrain that risk. In a bridge/swap context, hidden signing logic or chain-specific RPC assumptions can lead to unauthorized transfers, signing on the wrong network, or silent fund loss.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding
This finding points to materially risky behavior in the wider skill design: use of EVM_PRIVATE_KEY from local config and direct transaction signing/broadcasting are highly sensitive capabilities, yet the skill description and permission model do not clearly communicate or constrain that risk. In a bridge/swap context, hidden signing logic or chain-specific RPC assumptions can lead to unauthorized transfers, signing on the wrong network, or silent fund loss.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The README explicitly advertises automated transaction signing and sending using a locally stored private key, but it does not clearly warn users that invoking the skill can move real funds or that private-key material in ~/.openclaw/config.env is highly sensitive. In an agent-skill context, this increases the chance of unsafe deployment, accidental fund transfers, or poor key-handling practices because users may treat setup as routine automation rather than high-risk financial execution.

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill advertises and invokes shell scripts with network-capable dependencies but does not declare any explicit tool scope such as permissions or allowed-tools. That makes the skill's execution surface under-specified, increasing the chance that an agent may grant broader shell/network access than users expect for a transaction-capable skill that references private keys.

Vague Triggers

Medium
Confidence
96% confidence
Finding
The trigger phrase "tokens" is overly broad and can accidentally invoke the skill during ordinary conversation. In a skill that can lead users toward wallet-linked operations and transaction flows, ambiguous invocation increases the chance of unintended script execution, confusing prompts, or accidental progression toward sensitive actions.

External Transmission

Medium
Category
Data Exfiltration
Content
#!/bin/bash
# List supported chains from Relay Link API
curl -s "https://api.relay.link/chains" | jq '.chains[] | { name, id, displayName }'
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
#!/bin/bash
# List supported chains from Relay Link API
curl -s "https://api.relay.link/chains" | jq '.chains[] | { name, id, displayName }'
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
#!/bin/bash
# List supported chains from Relay Link API
curl -s "https://api.relay.link/chains" | jq '.chains[] | { name, id, displayName }'
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
#!/bin/bash
# List supported chains from Relay Link API
curl -s "https://api.relay.link/chains" | jq '.chains[] | { name, id, displayName }'
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
#!/bin/bash
# List supported chains from Relay Link API
curl -s "https://api.relay.link/chains" | jq '.chains[] | { name, id, displayName }'
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The script reads a private key and wallet addresses from a global user config file, giving the skill access to sensitive credentials beyond simple bridge quote generation. In this skill context, that access is especially dangerous because the same script later uses the key to sign and broadcast transactions, so installing or invoking the skill implicitly grants spending authority over the user's wallet.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script accesses a locally stored private key without an upfront warning that it will read wallet credentials from disk. In a bridge/swap skill, this is dangerous because the capability is coupled to transaction execution, meaning users may run the script expecting quote retrieval while unknowingly exposing or authorizing use of a highly sensitive signing secret.

External Transmission

Medium
Category
Data Exfiltration
Content
# Fallback to internal variables if not loaded (for better error messages)
USER_ADDR=${EVM_ADDRESS}
DEFAULT_RECIPIENT=${SOLANA_ADDRESS}
RPC_URL_AVAX="https://api.avax.network/ext/bc/C/rpc"

if [ -z "$USER_ADDR" ]; then echo "❌ Error: EVM_ADDRESS not found in $ENV_FILE"; exit 1; fi
if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then echo "Usage: $0 <amount> <origin_chain> <dest_chain>"; exit 1; fi
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
CONVERTED_AMOUNT=$(echo "$AMOUNT * 10^18" | bc | cut -d'.' -f1)

QUOTE=$(curl -s -X POST "https://api.relay.link/quote/v2" \
     -H "Content-Type: application/json" \
     -d "{
       \"user\": \"$USER_ADDR\",
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Context-Inappropriate Capability

Low
Confidence
86% confidence
Finding
The script reads a wallet address from a local config file and uses it for a broader account-history lookup when given a transaction hash. That exceeds a narrow 'status by ID/hash' function and introduces unnecessary access to user-specific data, which can expose wallet metadata and transaction associations to the remote service.

Missing User Warnings

Low
Confidence
92% confidence
Finding
The script sends the configured wallet address to Relay's API to enumerate request history, but the script comments and usage text do not clearly disclose that personal wallet metadata will be transmitted. This creates a privacy issue because users may expect a simple status check, not an account-history query tied to their address.

Intent-Code Divergence

Low
Confidence
95% confidence
Finding
Exporting the private key into the process environment does not materially secure it; environment variables can be exposed to subprocesses, debugging tools, crash logs, or other local inspection mechanisms. The misleading comment may cause users or maintainers to underestimate the sensitivity of this handling, while the script is actively preparing to sign a value-bearing blockchain transaction.

Static analysis

No suspicious patterns detected.