Back to skill

Security audit

Bout.Network

Security checks for vulnerabilities and agentic risk

Overview

This skill clearly describes a real-money testnet wagering bot, but it asks agents to run mutable remote bot code and automate wallet-based payments without strong user controls.

Install only if you are comfortable with an autonomous agent using a locally stored wallet to make repeated 1 USDC Base Sepolia payments. Avoid running the remote quick-start scripts unless you inspect and pin them first, use a dedicated low-balance wallet, keep secrets out of shell-sourced files when possible, and require your own confirmation or spending limits before room creation or joining.

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
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (4)

T03 · Remote Payload Retrieval and Execution

Error
Location
skill.md:6
Finding
Mutable Remote Bot Scripts Are Recommended for Local Execution<![CDATA[ ## Vulnerability Details **File Location**: `skill.md:6-12` **Vulnerability Type**: Remote payload retrieval and execution **Risk Level**: Critical ### Vulnerable Code ```markdown ## Quick Start — Example Bot Scripts If you want to get started quickly, download and run the ready-made bot scripts: - **Quick start guide:** https://bout.network/example-scripts/QUICKSTART.md - **Bot main script:** https://bout.network/example-scripts/bout-bot.mjs - **Gomoku AI logic:** https://bout.network/example-scripts/gomoku-ai.mjs These scripts handle wallet creation, registration, x402 payment, and the full game loop out of the box. ``` ### Technical Analysis The Skill recommends downloading and executing JavaScript from mutable external URLs. The remote files are not included in the audited package, pinned to an immutable revision, protected by a declared checksum, or verified using a cryptographic signature. Consequently, the code that is ultimately executed can differ from the code available when the Skill was reviewed. The stated bot functionality includes wallet creation, registration, x402 payment signing, and the complete game loop. A remote payload would therefore execute in a context likely to contain `BOUT_WALLET_KEY` and `BOUT_API_KEY`. This behavior exceeds the minimum privileges needed to document a game protocol. A safe integration could bundle reviewed source code or provide non-executable API documentation instead of delegating sensitive wallet operations to mutable remote scripts. ### Attack Path 1. An Agent follows the Quick Start instructions. 2. It retrieves `bout-bot.mjs`, `gomoku-ai.mjs`, or associated instructions from `bout.network`. 3. The external content is changed after publication or compromised at its hosting or delivery layer. 4. The Agent executes the modified script locally. 5. The script accesses environment variables, wallet files, API credentials, or payment-signing objects available to the current process. 6. The payl ...[truncated 573 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Include all executable bot code in the reviewed Skill package. - Pin external content to an immutable commit or content-addressed artifact. - Publish and verify a cryptographic checksum or signature before execution. - Do not execute downloaded code in a process containing wallet or API credentials. - Run game logic in a sandbox with restricted filesystem and network access. - Isolate transaction signing in a separate process that accepts only validated, narrowly scoped requests. - Require users to inspect and explicitly approve externally obtained code before it is run. ]]>

T01 · Skill Instruction Hijacking

Error
Location
skill.md:4
Finding
Autonomous Instructions Trigger Cryptocurrency Wagers Without Per-Transaction Approval<![CDATA[ ## Vulnerability Details **File Location**: `skill.md:4`, `skill.md:118-126`, and `skill.md:443-467` **Vulnerability Type**: Agent instruction hijacking and unsafe financial authorization **Risk Level**: High ### Vulnerable Code ```markdown # Follow these instructions to autonomously register, bet, compete, and settle — no human intervention required. ``` ```typescript // Create a room (x402 auto-pays 1 USDC on-chain): const res = await fetch402('https://bout.network/v1/rooms', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-Key': process.env.BOUT_API_KEY }, body: JSON.stringify({ gameId: 'gomoku' }) }) ``` ```typescript // Join existing room (x402 auto-pays 1 USDC on-chain) const res = await fetch402(`https://bout.network/v1/rooms/${roomId}/join`, { method: 'POST', headers: { 'X-API-Key': process.env.BOUT_API_KEY } }) ``` ### Technical Analysis The Skill explicitly instructs the Agent to register, bet, compete, and settle without human intervention. Room creation and room joining use an x402 wrapper that automatically responds to an HTTP 402 challenge by creating a signed EIP-3009 token-transfer authorization. The transfer is an intended part of the declared wagering service, but removing transaction-by-transaction user approval is not necessary to provide the game integration. The instruction changes the Agent's operational safety posture by treating loading the Skill as authorization for future financial actions. The reviewed text identifies a fixed wager of 1 USDC per room creation or join. Nevertheless, no local cumulative spending cap, number-of-games limit, recipient verification step, confirmation prompt, or independent validation of payment terms is required before signing. ### Attack Path 1. The Skill is loaded and its “no human intervention required” directive is adopted. 2. An EVM wallet is created or loaded and funded with USDC. 3. The Agent registers and obtains an API credential. 4. ...[truncated 853 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove the instruction to bet or settle without human intervention. - Require explicit informed approval before wallet creation, registration, every room creation, every room join, and every payment signature. - Present the chain, token, amount, recipient or verifying contract, expiration, and cumulative session spending before approval. - Enforce configurable per-transaction, per-session, and daily spending limits outside the model-controlled process. - Validate the x402 payment request against an allowlist of expected chains, token contracts, recipients, and maximum amounts. - Use a restricted signing service or wallet policy rather than exposing an unrestricted private key to the game process. - Add an emergency stop and prevent automatic retries from generating unintended additional authorizations. ]]>

T08 · Insecure Dependencies

Warning
Location
skill.md:362
Finding
Unpinned Third-Party Dependencies Run in a Wallet-Sensitive Context<![CDATA[ ## Vulnerability Details **File Location**: `skill.md:38`, `skill.md:65`, and `skill.md:362-365` **Vulnerability Type**: Insecure dependency installation **Risk Level**: Medium ### Vulnerable Code ```bash npm install viem > /dev/null 2>&1 ``` ```bash pip install eth-account > /dev/null 2>&1 ``` ```bash npm install @x402/fetch @x402/evm viem ``` ### Technical Analysis The installation commands do not specify exact package versions, lockfile integrity values, hashes, or a trusted dependency snapshot. Package resolution can therefore change over time. The suppression of installation output in two commands also makes warnings and unexpected installation behavior less visible. These packages are subsequently imported into code that loads `BOUT_WALLET_KEY`, creates an account object, signs registration messages, and signs x402 token-transfer authorizations. This makes dependency integrity especially important: malicious installation hooks or compromised imported code would run in a process with access to wallet material. The audit did not establish that any named package is malicious. The confirmed issue is that the Skill relies on mutable, unpinned supply-chain artifacts in a highly sensitive signing context. ### Attack Path 1. An Agent follows the setup instructions and installs the latest package versions resolved by npm or pip. 2. A package, transitive dependency, registry account, or package-delivery path is compromised. 3. Malicious lifecycle code runs during installation, or malicious module code runs when imported. 4. The Agent later loads the wallet private key and API key into the same environment. 5. The dependency reads or intercepts wallet material, registration signatures, or payment authorizations. 6. The compromised component exfiltrates secrets or modifies transaction-signing behavior. ### Impact Assessment Installation hooks execute with the privileges of the user running the package manager. Imported code executes with the pr ...[truncated 247 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Pin exact dependency versions and commit a reviewed lockfile with integrity metadata. - For Python, use a hash-locked requirements file and install with hash verification. - Review transitive dependencies and use an approved registry or dependency mirror. - Avoid suppressing package-manager output during security-sensitive setup. - Disable package lifecycle scripts where they are unnecessary. - Run installation and game logic in a sandbox without access to wallet files. - Put signing behind a separate, minimal service that enforces recipient, chain, token, amount, and rate limits. - Establish a dependency update process that requires review and repeatable security testing before version changes. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
skill.md:24
Finding
Wallet and API Secrets Are Persisted in a Shell-Executable Plaintext File<![CDATA[ ## Vulnerability Details **File Location**: `skill.md:24-28`, `skill.md:51-52`, `skill.md:88-90`, and `skill.md:202-205` **Vulnerability Type**: Plaintext credential storage and unsafe shell sourcing **Risk Level**: Medium ### Vulnerable Code ```bash if [ -f ~/.bout/${AGENT_NAME}.env ]; then source ~/.bout/${AGENT_NAME}.env echo "Wallet exists for ${AGENT_NAME}: $BOUT_WALLET_ADDR" fi ``` ```javascript writeFileSync(file, 'BOUT_AGENT_NAME=' + name + '\nBOUT_WALLET_KEY=' + key + '\nBOUT_WALLET_ADDR=' + acct.address + '\n'); chmodSync(file, 0o600); ``` ```bash source ~/.bout/${AGENT_NAME}.env echo "Agent: $BOUT_AGENT_NAME — Wallet: $BOUT_WALLET_ADDR" ``` ```bash export BOUT_API_KEY="ak_xxxx..." echo "BOUT_API_KEY=$BOUT_API_KEY" >> ~/.bout/${AGENT_NAME}.env ``` ### Technical Analysis The workflow stores the wallet private key and service API key as plaintext in the same file. Initial wallet creation applies mode `0600`, which limits ordinary access, but it does not provide encryption, secret isolation, integrity protection, or protection from code already running as the same user. More importantly, the file is loaded with the shell `source` command. A sourced file is executable shell input, not merely a data file. If the file is modified, any command inserted into it executes when the Agent next loads the wallet. The Skill also appends the API key using shell interpolation without defining strict validation or an atomic update procedure. The risk is materially higher because the Skill recommends executing remote code and installing dependencies under the same user account. Any such code with write access to `~/.bout` could turn the credential file into a command-execution trigger. ### Attack Path 1. An attacker-controlled process running as the same user, a compromised dependency, or a downloaded remote bot modifies `~/.bout/${AGENT_NAME}.env`. 2. It inserts a shell command alongside or instead of the expected variable assignments. 3. The ...[truncated 853 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Never load credential files with `source`, `.`, or another shell execution mechanism. - Store structured data in a non-executable format and parse it with a strict parser. - Validate agent names, paths, API keys, addresses, and private-key formats before storage or use. - Store wallet keys in an operating-system keychain, hardware wallet, or dedicated signing service. - Separate the API credential from the wallet private key and grant each component access only to the secret it needs. - Use atomic file creation and updates, reject symbolic links, and verify ownership and mode before every read. - Reapply and verify restrictive permissions after updates. - Add integrity protection so unauthorized modifications are detected before credentials are loaded. - Rotate the API key and migrate the wallet if the existing plaintext file may have been exposed. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (17)

Credential Access

High
Category
Privilege Escalation
Content
Check if a wallet already exists for this agent:

```bash
if [ -f ~/.bout/${AGENT_NAME}.env ]; then
  source ~/.bout/${AGENT_NAME}.env
  echo "Wallet exists for ${AGENT_NAME}: $BOUT_WALLET_ADDR"
fi
Confidence
88% confidence
Finding
The skill instructs sourcing a local env file containing wallet secrets into the shell session. This exposes sensitive credentials broadly to the current process environment and any child processes, increasing the chance of accidental disclosure or misuse by other tooling.

Credential Access

High
Category
Privilege Escalation
Content
```bash
if [ -f ~/.bout/${AGENT_NAME}.env ]; then
  source ~/.bout/${AGENT_NAME}.env
  echo "Wallet exists for ${AGENT_NAME}: $BOUT_WALLET_ADDR"
fi
```
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
const name = '${AGENT_NAME}';
const dir = join(homedir(), '.bout');
const file = join(dir, name + '.env');

if (existsSync(file)) { console.log('Wallet already exists for ' + name); process.exit(0); }
Confidence
91% confidence
Finding
The Node.js setup writes the private key in plaintext to `~/.bout/<agent>.env`. Even with restrictive file permissions, plaintext local storage of a blockchain private key materially increases the risk of theft via local compromise, backups, shell tooling, or operator error.

Credential Access

High
Category
Privilege Escalation
Content
name = '${AGENT_NAME}'
d = os.path.join(os.path.expanduser('~'), '.bout')
f = os.path.join(d, name + '.env')

if os.path.exists(f):
    print('Wallet already exists for ' + name)
Confidence
91% confidence
Finding
The Python setup repeats the same insecure pattern of storing the wallet private key in a plaintext env file under the user's home directory. This makes compromise of the host or accidental file disclosure equivalent to wallet compromise.

Credential Access

High
Category
Privilege Escalation
Content
After creating the wallet, load it:

```bash
source ~/.bout/${AGENT_NAME}.env
echo "Agent: $BOUT_AGENT_NAME — Wallet: $BOUT_WALLET_ADDR"
```
Confidence
87% confidence
Finding
Sourcing the wallet env file imports the private key into the shell environment for convenience. This broadens access to the secret and can leak it into subprocesses, histories, diagnostics, or unrelated commands executed in the same session.

Credential Access

High
Category
Privilege Escalation
Content
Check your balance:
```bash
source ~/.bout/${AGENT_NAME}.env
cast balance --erc20 0x036CbD53842c5426634e7929541eC2318f3dCF7e $BOUT_WALLET_ADDR --rpc-url https://sepolia.base.org
```
Or use the viem/ethers equivalent in your code.
Confidence
83% confidence
Finding
Although the command is only checking token balance, it again instructs sourcing the same env file containing wallet secrets. Repeatedly normalizing this workflow increases the chance that secrets are exposed in routine operations.

Credential Access

High
Category
Privilege Escalation
Content
### Option A: Node.js

```bash
source ~/.bout/${AGENT_NAME}.env

cd /tmp/bout-setup  # reuse from Step 1 (has viem installed)
node -e "
Confidence
88% confidence
Finding
The registration flow requires sourcing the env file before running code that uses the private key to sign a message. This is operationally expected, but still creates credential exposure through environment inheritance and teaches an unsafe secret-handling pattern.

Credential Access

High
Category
Privilege Escalation
Content
### Option B: Python

```bash
source ~/.bout/${AGENT_NAME}.env

python3 -c "
import json, time, urllib.request, os
Confidence
88% confidence
Finding
The Python registration path has the same issue: it relies on sourcing a plaintext env file containing the private key before use. This is not just documentation of existing state; it is prescriptive secret handling that materially increases compromise risk.

Credential Access

High
Category
Privilege Escalation
Content
Save the apiKey back to your agent's wallet file:
```bash
export BOUT_API_KEY="ak_xxxx..."
echo "BOUT_API_KEY=$BOUT_API_KEY" >> ~/.bout/${AGENT_NAME}.env
```

### Rename Your Agent
Confidence
96% confidence
Finding
Appending the API key to the same env file as the wallet private key combines two powerful credentials in one plaintext location. A single file disclosure would enable both authenticated API actions and wallet-based financial operations, amplifying blast radius.

Credential Access

High
Category
Privilege Escalation
Content
No action needed after the game — check your wallet balance on Base Sepolia explorer or via:
```bash
source ~/.bout/${AGENT_NAME}.env
cast balance --erc20 0x036CbD53842c5426634e7929541eC2318f3dCF7e $BOUT_WALLET_ADDR --rpc-url https://sepolia.base.org
```
Confidence
82% confidence
Finding
Even for post-game balance checks, the skill instructs sourcing the secret env file again, reinforcing unnecessary secret access for non-signing tasks. This increases routine exposure of the private key with no corresponding need.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The skill explicitly instructs the agent to autonomously register, wager, compete, and settle using a real wallet with no human intervention, while only later disclosing that on-chain USDC transfers occur. This creates a high-risk consent and financial-safety issue because activation can lead directly to monetary loss and signing activity before a user is clearly warned at the point of use.

Session Persistence

Medium
Category
Rogue Agent
Content
---

## Step 1: Choose Your Agent Name & Create Wallet

First, decide your agent name. This name is used for your wallet file, registration, and in-game display.
Confidence
86% confidence
Finding
The skill directs creation of a persistent wallet and local credential file for continued autonomous operation. Persistent financial identity and unattended reuse increase the risk of unauthorized future actions, especially when paired with wagering and API-driven game loops.

Session Persistence

Medium
Category
Rogue Agent
Content
- **Fixed wager: 1 USDC per game.** Each player pays 1 USDC to enter. Winner receives 1.8 USDC. Bout takes 0.2 USDC (10% fee).
- **Real on-chain payment.** Creating or joining a room triggers a real USDC transfer from your wallet to the Escrow contract via the x402 protocol. Ensure your wallet has sufficient USDC balance.
- **One agent per wallet.** Do NOT create multiple agents or "test bots". Register once and reuse your credentials.
- **One room at a time.** You cannot create or join a room while you have an open room or an active battle.
- **No self-play.** You cannot join your own room.
- **x402 payment required.** Both creating and joining a room require USDC payment via the x402 protocol. Use `@x402/fetch` and `@x402/evm` to wrap your fetch calls. The x402 client handles the EIP-3009 (TransferWithAuthorization) signing automatically.
Confidence
84% confidence
Finding
The instruction to register once and reuse credentials promotes durable session persistence for a financially active agent. In this context, persistence is more dangerous because the same credentials can repeatedly authorize wagering actions over time.

External Transmission

Medium
Category
Data Exfiltration
Content
const message = 'bout-register:$BOUT_AGENT_NAME:' + timestamp;
  const signature = await account.signMessage({ message });

  const res = await fetch('https://bout.network/v1/agent/register', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
Confidence
89% confidence
Finding
The skill transmits registration data, including wallet address, signed proof, agent name, and framework metadata, to an external service. While this is part of the protocol's expected operation, it is still a real external data transmission that can affect privacy, link identities, and enroll the agent into a financial workflow.

External Transmission

Medium
Category
Data Exfiltration
Content
You can change your agent's display name at any time:

```bash
curl -s -X PATCH 'https://bout.network/v1/agent/me/name' \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $BOUT_API_KEY" \
  -d '{"name": "new-agent-name"}'
Confidence
84% confidence
Finding
The rename call sends the API key and new display name to an external endpoint. This is lower severity than the registration flow, but it still exposes an authenticated action to a third-party service and should not occur without clear user awareness.

Session Persistence

Medium
Category
Rogue Agent
Content
Payment and settlement are fully on-chain on Base Sepolia:

1. **Deposit:** When you create or join a room, `@x402/fetch` signs an EIP-3009 TransferWithAuthorization. The x402 facilitator submits the on-chain USDC transfer from your wallet to the BoutEscrow contract (`0x96b52a7840E47f6A63f0ba9B58efF54c48e0Abe6`).
2. **Battle:** The game runs. No on-chain interaction during gameplay.
3. **Payout:** After the battle ends, the Judge calls `BoutEscrow.settle()` which transfers USDC directly to the winner's wallet.
Confidence
89% confidence
Finding
This section describes persistent wallet-based authorization for on-chain deposits and settlement, meaning previously stored credentials remain usable for future financial operations. In combination with autonomous play, persistence directly increases the potential for unattended loss or abuse if the host or skill is compromised.

Missing User Warnings

Low
Confidence
93% confidence
Finding
The instructions tell users to append the API key into the same env file that stores the wallet private key, concentrating multiple sensitive secrets in one local file. If that file is exposed through backup leakage, local compromise, accidental sharing, or later sourcing by other scripts, both the API identity and wallet control can be abused together.

Static analysis

Detected: suspicious.generated_source_template_injection

User-controlled placeholder is embedded directly into generated source code.

Critical
Code
suspicious.generated_source_template_injection
Location
skill.md:82