Back to skill

Security audit

Solana Sniper Bot

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed Solana trading bot, but it asks for live wallet authority and automatic trading while important advertised safeguards are missing or unsafe.

Install only after treating this as experimental live-trading code: use a dedicated low-balance wallet, assume automatic buys can lose the entire funded amount, do not rely on the advertised stop-loss/take-profit or auto-sell behavior, and review/fix transaction signing and validation before running with real funds.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/sniper.py:126
Finding
Remote Swap Transaction Is Not Semantically Validated Before Signing and Submission<![CDATA[ ## Vulnerability Details **File Location**: `scripts/sniper.py:126-151` **Vulnerability Type**: Unvalidated remote transaction signing **Risk Level**: High ### Complete Code Snippet ```python async def execute_swap(quote: dict) -> dict: """Execute swap via Jupiter.""" from solders.keypair import Keypair import base58 keypair = Keypair.from_bytes(base58.b58decode(PRIVATE_KEY)) async with httpx.AsyncClient(timeout=30) as client: resp = await client.post(JUPITER_SWAP, json={ "quoteResponse": quote, "userPublicKey": str(keypair.pubkey()), "wrapAndUnwrapSol": True }) swap_data = resp.json() # Sign and send transaction from solders.transaction import VersionedTransaction import base64 tx_bytes = base64.b64decode(swap_data["swapTransaction"]) tx = VersionedTransaction.from_bytes(tx_bytes) signed = keypair.sign_message(tx.message.serialize()) rpc = get_rpc_url() send_resp = await client.post(rpc, json={ "jsonrpc": "2.0", "id": 1, "method": "sendTransaction", "params": [base64.b64encode(bytes(tx)).decode(), {"skipPreflight": True}] }) return send_resp.json() ``` ### Technical Analysis The Skill treats the serialized transaction returned by the remote Jupiter endpoint as trusted. It decodes the transaction and proceeds toward signing without inspecting its instructions, program IDs, writable accounts, recipients, transfer amounts, output mint, fee recipients, or address lookup tables. TLS reduces ordinary network interception risk, but it does not protect against compromise of the Jupiter service, DNS or certificate trust infrastructure, or an upstream dependency. A compromised service could return a transaction materially different from the requested swap. The use of `"skipPreflight": True` further removes RPC simulation that could otherwise detect some transaction fail ...[truncated 1629 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Decode and inspect every instruction before signing. - Allowlist the expected Jupiter and Solana program IDs. - Verify the input mint, output mint, maximum input amount, minimum output amount, slippage, recipient, fee accounts, and all writable accounts. - Reject unexpected transfers, approvals, program invocations, address lookup tables, or additional signers. - Compare the transaction against the locally retained quote rather than trusting the swap response. - Enable RPC preflight simulation and inspect simulation errors and balance changes. - Pin and authenticate the expected API endpoint. - Use a dedicated wallet funded only with the maximum acceptable trading loss. - Add unit and integration tests using intentionally manipulated swap transactions. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/sniper.py:139
Finding
Computed Transaction Signature Is Never Attached to the Submitted Transaction<![CDATA[ ## Vulnerability Details **File Location**: `scripts/sniper.py:139-147` **Vulnerability Type**: Incorrect Solana transaction signing **Risk Level**: Medium ### Complete Code Snippet ```python from solders.transaction import VersionedTransaction import base64 tx_bytes = base64.b64decode(swap_data["swapTransaction"]) tx = VersionedTransaction.from_bytes(tx_bytes) signed = keypair.sign_message(tx.message.serialize()) rpc = get_rpc_url() send_resp = await client.post(rpc, json={ "jsonrpc": "2.0", "id": 1, "method": "sendTransaction", "params": [base64.b64encode(bytes(tx)).decode(), {"skipPreflight": True}] }) ``` ### Technical Analysis `keypair.sign_message(...)` produces a signature and assigns it to `signed`, but that value is never inserted into the `VersionedTransaction`. The code then serializes and submits `tx`, which remains the transaction originally returned by the API. A Solana transaction must contain valid signatures corresponding to its required signer positions. Computing a detached signature without updating or reconstructing the transaction does not sign the serialized transaction being submitted. ### Attack Path 1. A token passes the bot's risk threshold. 2. The bot obtains a Jupiter transaction. 3. The bot calculates a detached signature. 4. The signature is discarded because `signed` is never used. 5. The original transaction is serialized and sent to the RPC endpoint. 6. The RPC node rejects the missing or invalid signature. 7. The bot logs a failed or unknown purchase while continuing to monitor and attempt additional trades. ### Impact Assessment The advertised autonomous purchase functionality will generally fail. This is primarily an integrity and availability defect rather than a direct privilege-escalation issue. In a live financial system, repeated signing failures can cause missed entries, misleading trade records, operational co ...[truncated 237 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Construct a properly signed `VersionedTransaction` using the supported `solders` API. - Insert signatures in the correct required-signer order. - Verify all signatures locally before serialization and RPC submission. - Do not merely replace the current code with working blind signing; first implement the semantic transaction validation described in the preceding finding. - Add tests that deserialize the submitted bytes and verify that the expected public key has a valid signature over the exact submitted message. - Treat missing signatures, malformed transactions, and unexpected signer counts as hard failures. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/setup.sh:1
Finding
Dependency Installation Lacks Package Integrity Verification<![CDATA[ ## Vulnerability Details **File Location**: `scripts/setup.sh:1-5` **Vulnerability Type**: Unverified third-party dependency installation **Risk Level**: Medium ### Complete Code Snippet ```bash #!/bin/bash set -e echo "=== Solana Sniper Bot Setup ===" pip install solana==0.35.0 solders==0.21.0 httpx==0.27.0 aiohttp==3.9.5 python-dotenv==1.0.1 base58==2.1.1 echo "Done. Create .env with SOLANA_PRIVATE_KEY and LLM_API_KEY" ``` ### Technical Analysis The packages are version-pinned, which improves reproducibility, but their distribution hashes are not verified. The command also uses the ambient `pip` configuration and package index. If a configured package mirror, package publisher account, DNS path, or index infrastructure is compromised, a substituted package distribution could be installed. Python packages may execute code during installation or later when imported by the bot. No evidence was found that any listed dependency is currently malicious. The issue is the absence of supply-chain integrity controls in an environment intended to hold a wallet private key and an LLM API key. ### Attack Path 1. An attacker compromises a package publisher, configured Python package mirror, or dependency distribution path. 2. A malicious distribution is made available under one of the pinned package names and versions. 3. The operator runs `scripts/setup.sh`. 4. `pip` downloads the distribution without checking a project-approved cryptographic hash. 5. Malicious package code executes during installation or import. 6. The code gains the privileges of the installing user and may read the bot's files, environment variables, wallet private key, and API credentials. ### Impact Assessment Successful exploitation could provide arbitrary code execution with the privileges of the user running setup or the bot. If installation is run as root, system-wide compromise may be possible. Otherwise, the likely scope includes the user's files, process credentials, enviro ...[truncated 81 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Generate a reviewed lock file containing hashes for every direct and transitive dependency. - Install with `pip install --require-hashes -r requirements.txt`. - Specify an approved HTTPS package index explicitly. - Use a dedicated virtual environment and avoid running installation as root. - Scan locked packages for known vulnerabilities and review dependency updates. - Consider storing internally verified package artifacts in a controlled repository. - Separate installation from the runtime environment containing wallet and API secrets. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:50
Finding
Documented Risk and Exit Controls Are Not Implemented<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:50-77` **Vulnerability Type**: Misleading security and trading-control claims **Risk Level**: High ### Complete Code Snippet ```markdown ## How It Works 1. **Pool Monitor** — Watches Raydium AMM for new liquidity pool creation events 2. **Token Analysis** — For each new pool, queries token metadata: - Mint authority (revoked = good) - Freeze authority (revoked = good) - LP burned/locked percentage - Top holder concentration - Contract verification status 3. **LLM Risk Assessment** — Sends token data to Claude Haiku for rugpull probability estimate 4. **Auto-Buy** — If risk score < threshold, buys via Jupiter aggregator for best price 5. **Position Management** — Monitors positions with take-profit and stop-loss triggers 6. **Auto-Sell** — Exits via Jupiter when TP/SL hit ## Risk Scoring Each token gets scored 0-100 (lower = safer): | Factor | Weight | Red Flag | |--------|--------|----------| | Mint authority | 25% | Not revoked | | Freeze authority | 20% | Not revoked | | LP lock | 20% | < 80% locked | | Top 10 holders | 15% | > 50% supply | | Contract age | 10% | < 1 hour | | LLM sentiment | 10% | Negative assessment | Default buy threshold: risk score < 40 ``` ### Technical Analysis The implementation only evaluates mint authority, freeze authority, and holder concentration before incorporating a generic LLM score. It does not retrieve or validate LP lock or burn status, contract verification, contract age, social data, or several other documented risk factors. The script also has no position-monitoring loop, price tracking, sell quote flow, or sell transaction path. `TAKE_PROFIT` and `STOP_LOSS` are loaded and logged but never enforced. Positions exist only in process memory and an append-only trade log. This discrepancy is security-relevant because users are asked to provide a private key and permit unattended purchases based on assurances that material risk controls ...[truncated 1261 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Disable live trading by default until all documented controls are implemented and tested. - Implement verifiable LP lock and burn checks using authoritative on-chain data. - Implement token-age and verification checks, or remove those claims. - Add persistent position tracking, price monitoring, take-profit, stop-loss, and a tested sell path. - Reconcile the documented weighting table with the actual scoring algorithm. - Clearly distinguish implemented, experimental, and planned capabilities. - Require explicit user confirmation before enabling autonomous purchases. - Add maximum daily loss, maximum wallet exposure, per-token limits, and an emergency stop. - Provide dry-run and simulation modes as the default operating modes. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
SKILL.md:21
Finding
Setup Documentation Executes a Bash Script with the Python Interpreter<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:21-23` **Vulnerability Type**: Invalid installation command **Risk Level**: Low ### Complete Code Snippet ```bash python3 {baseDir}/scripts/setup.sh ``` ### Technical Analysis `scripts/setup.sh` is a Bash script, but the documented command passes it to the Python interpreter. Python will attempt to parse shell syntax such as `set -e` and fail. This is not a direct code-execution vulnerability, but it makes the supported installation path unreliable. In a security-sensitive wallet application, failed official setup instructions can encourage users to improvise with elevated privileges, unreviewed commands, or globally installed packages. ### Attack Path 1. The operator follows the documented setup command. 2. Python attempts to parse the Bash script. 3. Installation fails with a syntax error. 4. The operator searches for or copies an unofficial workaround. 5. If that workaround is malicious or uses unnecessary elevated privileges, the operator may expose the system or bot credentials. The final step depends on external user action; the project itself does not directly execute an attacker-controlled fallback. ### Impact Assessment The direct impact is loss of setup availability and reliability. Indirectly, it can increase supply-chain and privilege risk by pushing users toward ad-hoc installation methods. No direct unauthorized privileges are obtained from the documented command alone. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Replace the command with: ```bash bash {baseDir}/scripts/setup.sh ``` - Prefer a virtual-environment installation workflow. - Add a shell syntax check and installation smoke test to continuous integration. - Document that setup should not be run as root. - Keep the manual installation instructions synchronized with the setup script and hash-locked dependency file. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • 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 (11)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The skill promises autonomous risk evaluation, monitoring, portfolio management, and take-profit/stop-loss behavior, but the analyzed behavior reportedly lacks key safety and control features. In an autonomous trading context, this mismatch is dangerous because users may entrust funds based on protections that are not actually implemented, leading to unmanaged exposure and potentially irreversible losses.

Credential Access

High
Category
Privilege Escalation
Content
set -e
echo "=== Solana Sniper Bot Setup ==="
pip install solana==0.35.0 solders==0.21.0 httpx==0.27.0 aiohttp==3.9.5 python-dotenv==1.0.1 base58==2.1.1
echo "Done. Create .env with SOLANA_PRIVATE_KEY and LLM_API_KEY"
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Missing User Warnings

High
Confidence
98% confidence
Finding
The bot performs automatic on-chain purchases whenever its internal risk score is below threshold, without any user confirmation, approval workflow, or interactive warning. In the context of an autonomous sniper bot controlling real funds, this is especially dangerous because API manipulation, bad heuristics, or false positives can immediately trigger irreversible purchases of malicious or illiquid tokens.

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill advertises and requires sensitive capabilities—environment secrets, file deployment steps, and outbound network access—without explicitly declaring a constrained tool scope. In a skill that handles a Solana private key and can place trades, missing capability boundaries increases the chance of overbroad execution, secret exposure, or unintended external actions.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The manifest description says to use the skill when a user wants to "trade memecoins" or "build a Solana trading bot," which are broad intents rather than specific activation triggers. Without tighter scope or exclusion conditions, the skill could be invoked for general crypto discussions or benign trading help beyond sniper-bot use cases.

Missing User Warnings

Medium
Confidence
85% confidence
Finding
The code reads SOLANA_PRIVATE_KEY directly from the environment and later uses it to sign transactions, but there is no visible warning, prompt, or explanatory comment alerting the user that a live private key is required. Access to highly sensitive credentials should be explicitly disclosed because misuse or accidental execution can compromise funds.

External Transmission

Medium
Category
Data Exfiltration
Content
Reply with ONLY a number 0.0 to 1.0."""

    async with httpx.AsyncClient(timeout=30) as client:
        resp = await client.post("https://api.anthropic.com/v1/messages",
            headers={"x-api-key": LLM_API_KEY, "anthropic-version": "2023-06-01", "Content-Type": "application/json"},
            json={"model": "claude-3-5-haiku-20241022", "max_tokens": 20, "messages": [{"role": "user", "content": prompt}]})
        data = resp.json()
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The code decodes a Jupiter swap transaction, computes a signature, but never applies that signature to the transaction before sending base64-encoded original transaction bytes with skipPreflight enabled. In a trading bot that autonomously places live trades, this can cause failed, malformed, or unpredictable transaction submission behavior and undermines the claim that swaps are safely executed.

External Transmission

Medium
Category
Data Exfiltration
Content
try:
            async with httpx.AsyncClient(timeout=15) as client:
                # Check for new Raydium AMM pools
                resp = await client.get("https://api.raydium.io/v2/ammV3/ammPools")
                pools = resp.json().get("data", [])

                for pool in pools[-20:]:  # Check latest 20
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
try:
            async with httpx.AsyncClient(timeout=15) as client:
                # Check for new Raydium AMM pools
                resp = await client.get("https://api.raydium.io/v2/ammV3/ammPools")
                pools = resp.json().get("data", [])

                for pool in pools[-20:]:  # Check latest 20
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

Low
Confidence
82% confidence
Finding
The manifest says the bot 'Monitors new token launches on Raydium/Jupiter,' implying launch discovery across both venues. In the implementation, new-pool monitoring is performed only by polling Raydium's AMM pools API, while Jupiter is used later only for quote and swap execution, not launch monitoring.

Static analysis

No suspicious patterns detected.