Back to skill

Security audit

Crypto Sniping

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed Binance trading bot, but it can place real trades automatically and its safety controls are under-scoped for that level of financial authority.

Review this carefully before installing. Use only a dedicated restricted Binance API key with no withdrawal permission, start without live trading, assume Telegram alerts may reveal trading activity, and do not rely on the advertised stop-loss or take-profit behavior until the live exit-order and paper-mode credential issues are fixed.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
src/trader.py:251
Finding

Live Positions Are Recorded as Closed Without Executing an Exchange Exit Order

Content
View full analysis
= position.stop_loss: self._close_position(position, current_price, "STOP_LOSS") return # Check take profits for tier in position.take_profits: if tier["hit"]: continue tp_price = tier["price"] if (position.side == "BUY" and current_price >= tp_price) or \ (position.side == "SELL" and current_price <= tp_price): # In real trading, this would partially close the position tier["hit"] = True logging.info(f"Take profit hit for {position.symbol} at ${tp_price:.2f}") # If all TPs hit, close position if all(t["hit"] for t in position.take_profits): self._close_position(position, current_price, "TAKE_PROFIT") def _close_position(self, position: Position, exit_price: float, reason: str): """Close a position.""" # Calculate P&L if position.side == "BUY": pnl = (exit_price - position.entry_price) * position.quantity pnl_percent = (exit_price - position.entry_price) / position.entry_price * 100 else: pnl = (position.entry_price - exit_price) * position.quantity pnl_percent = (position.entry_price - exit_price) / position.entry_price * 100 # Update database conn = sqlite3.connect(self.db_path) cursor = conn.cursor() cursor.execute(""" UPDATE trades SET ...[truncated 2720 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
src/binance_client.py:41
Finding

Binance API Requests Have No Connection or Read Timeouts

Content
View full analysis
Dict: """Make API request.""" base = self.FAPI_URL if futures else self.BASE_URL url = f"{base}{endpoint}" if params is None: params = {} if signed: params["timestamp"] = self._get_timestamp() query_string = urlencode(params) params["signature"] = self._generate_signature(query_string) if method == "GET": response = self.session.get(url, params=params) elif method == "POST": response = self.session.post(url, data=params) elif method == "DELETE": response = self.session.delete(url, params=params) else: raise ValueError(f"Unsupported HTTP method: {method}") response.raise_for_status() return response.json() ``` ### Technical Analysis The `requests.Session` calls do not specify a timeout. Python Requests does not impose a default overall timeout, so a connection or response that stops progressing can block the calling thread indefinitely. The trading bot processes position checks and signal operations serially. A blocked request can therefore suspend the entire control loop, including polling-based stop-loss and take-profit evaluation. Exception handling does not mitigate this condition because no exception is necessarily raised while the request remains blocked. ### Attack Path 1. A live position is opened and depends on the bot's polling loop for exit evaluation. 2. A request to Binance encounters a stalled connection, an indefinitely delayed response, or a network path that does not terminate cleanly. 3. Because no timeout is configured, the request blocks the only trading-loop thread. 4 ...[truncated 884 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
src/binance_client.py:16
Finding

Paper Trading Requires and Uses Real Binance Account Credentials

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (13)

YARA rule 'agent_skill_credential_exfiltration_webhook': AI agent skill credential harvesting followed by webhook or external exfiltration [agent_skills]

Critical
Category
YARA Match
Confidence
85% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · src/notifier.py (reported line 16)May include surrounding context.

python
port os
from typing import Optional
import requests

from .signals import Signal
from .trader import Trade, Position
from .whale_tracker import WhaleAlert

class Notifier:
    """Send notifications via Telegram and logging."""
    
    def __init__(self, telegram_token: Optional[str] = None, 
                 telegram_chat_id: Optional[str] = None):
        self.telegram_token = telegram_token or os.getenv("TELEGRAM_BOT_TOKEN")
        self.telegram_chat_id = telegram_chat_id or os.getenv("TELEGRAM_CHAT_ID")
        self.enabled = bool(self.telegram_token and self.telegram_chat_id)
        
        if not self.enabled:
            logging.warning("Telegram notifications disabled - set TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID")
    
    def _send_telegram(self, message: str):
        """Send message via Telegram."""
        if not self.enabled:
            return
        
        try:
            url = f"https://api.telegram.org/bot{self.telegram_token}/sendMessage"
            payload =

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill provides a direct --live command for automated trading immediately after a brief test-mode step, but it does not place an explicit, prominent warning at that invocation point about real financial loss, slippage, volatility, and the risk of unattended order execution. In a trading bot context, this omission can cause users to transition to live trading without fully appreciating that the skill may place real market orders with immediate monetary consequences.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The place_order method submits a signed POST request to Binance to create a live order, which can directly affect user funds. Although the method has a minimal docstring, there is no visible confirmation prompt, user-facing log/print, or warning in this file indicating that it will place a real trade.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The cancel_order method issues a signed DELETE request to cancel an exchange order, which is a safety-relevant account operation. The code contains only a brief docstring and no confirmation prompt, logging, or other disclosure to the user about the action being taken.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The main execution path automatically places trades for signals with confidence >= 4 without any interactive confirmation, dry-run gate, or explicit runtime acknowledgement beyond a startup log message. In a trading bot context, this is dangerous because a misconfiguration, faulty signal source, compromised dependency, or unexpected market condition can trigger real orders and financial loss immediately once the bot is started in live mode.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · src/notifier.py (reported line 29)May include surrounding context.

python
return
        
        try:
            url = f"https://api.telegram.org/bot{self.telegram_token}/sendMessage"
            payload = {
                "chat_id": self.telegram_chat_id,
                "text": message,

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · src/notifier.py (reported line 35)May include surrounding context.

python
"text": message,
                "parse_mode": "Markdown"
            }
            requests.post(url, json=payload, timeout=5)
        except Exception as e:
            logging.error(f"Failed to send Telegram message: {e}")

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency is specified with a lower bound only, which allows different versions to be installed over time and makes builds non-reproducible. This increases supply-chain risk because a newly released vulnerable or incompatible version of requests could be pulled in without review.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
requests>=2.31.0
pyyaml>=6.0
numpy>=1.24.0

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
88% confidence
Finding

Requests has known advisories, and because the manifest does not pin the exact installed version, it is impossible to verify from this file alone whether the deployed package is affected. The danger is uncertainty: environments may resolve to versions with known flaws, including credential leakage and other request-handling issues.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

PyYAML is not pinned to a specific version, so installations may resolve to different releases across environments and time. Because PyYAML has had multiple security issues historically, leaving the version open-ended increases the chance of unintentionally consuming an affected release.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
requests>=2.31.0
pyyaml>=6.0
numpy>=1.24.0

Unverifiable Dependency: pyyaml has 8 known advisory(ies) (CVE-2019-20477 (Deserialization of Untrusted Data in PyYAML); CVE-2020-1747 (Improper Input Validation in PyYAML); CVE-2020-14343 (Improper Input Validation in PyYAML) +5 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
92% confidence
Finding

PyYAML has a history of serious vulnerabilities, including unsafe deserialization-related issues, and the unpinned requirement prevents verification of the resolved version. If the skill later parses untrusted YAML, an affected version could materially increase the risk of code execution or other unsafe behavior.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

NumPy is declared with only a minimum version, which permits unreviewed version drift and reduces reproducibility. While often treated as hygiene, this is still a supply-chain weakness because vulnerable or breaking releases may be installed automatically.

Content

Scanner excerpt · requirements.txt (reported line 3)May include surrounding context.

text
requests>=2.31.0
pyyaml>=6.0
numpy>=1.24.0

Unverifiable Dependency: numpy has 16 known advisory(ies) (CVE-2014-1859 (Numpy arbitrary file write via symlink attack); CVE-2021-41495 (NumPy NULL Pointer Dereference); CVE-2021-33430 (NumPy Buffer Overflow (Disputed)) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
86% confidence
Finding

NumPy has published advisories, and the lack of an exact version means the actual security posture cannot be determined from this requirements file. This creates a supply-chain verification gap where vulnerable versions could be installed in some environments without visibility.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.