Back to skill

Security audit

Neko Futures Trader

Security checks for vulnerabilities and agentic risk

Overview

This is a real automated Binance futures trading skill, but it has serious review-worthy risks around public dashboard exposure, secret handling, and automatic leveraged order execution.

Review before installing. Use only test or tightly scoped, IP-restricted Binance keys, do not expose the dashboard to a public network, remove any instruction that prints .env contents, and fix the order-management and dependency issues before using real funds. Rotate Binance and Telegram credentials if this code or dashboard has already run on an exposed host.

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
dashboard_api.py:102
Finding
Unauthenticated Dashboard Exposes Private Account Data and Workspace Files<![CDATA[ ## Vulnerability Details **File Location**: `dashboard_api.py:102-164` **Vulnerability Type**: Unauthenticated sensitive-data and arbitrary workspace-file exposure **Risk Level**: Critical ### Vulnerable Code ```python class H(BaseHTTPRequestHandler): def do_GET(self): if self.path.startswith('/api'): self._handle_api() else: self._serve_static() def _handle_api(self): try: data = get_account_data() except Exception as e: data = {'err': str(e), 'bal': 0.0, 'pnl': 0.0, 'pos': []} body = json.dumps(data).encode() self.send_response(200) self.send_header('Content-Type', 'application/json') self.send_header('Access-Control-Allow-Origin', '*') self.send_header('Cache-Control', 'no-store') self.end_headers() self.wfile.write(body) def _serve_static(self): """Serve files from /root/.openclaw/workspace/, limited to that directory tree.""" if '..' in self.path: self.send_error(403, 'Forbidden') return if self.path == '/': file_path = '/root/.openclaw/workspace/index.html' else: file_path = '/root/.openclaw/workspace' + self.path if not os.path.isfile(file_path): self.send_error(404, 'Not Found') return mime = mimetypes.guess_type(file_path)[0] or 'application/octet-stream' try: with open(file_path, 'rb') as f: body = f.read() ``` ```python if __name__ == '__main__': server = ThreadedHTTPServer(('0.0.0.0', 8080), H) print('[dashboard_api] Listening on 0.0.0.0:8080') server.serve_forever() ``` ### Technical Analysis The dashboard binds to every network interface and implements no authentication or authorization. Any reachable client can call `/api` and receive private Binance account information, including balance, PnL, symbols, position dire ...[truncated 1831 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Bind the service to `127.0.0.1` by default and expose it only through an authenticated reverse proxy with TLS. 2. Require authentication and authorization for `/api` and all static resources. 3. Serve files exclusively from a dedicated public-assets directory using canonical path validation. 4. Maintain an explicit file allowlist and reject dotfiles, configuration files, logs, caches, and symbolic links. 5. Remove `Access-Control-Allow-Origin: *`; configure an exact trusted origin if cross-origin access is required. 6. Return only the minimum dashboard fields needed and avoid exposing position amounts or entry details unnecessarily. 7. Add rate limiting, security logging, secure response headers, and network firewall restrictions. 8. Rotate Binance and Telegram credentials if this dashboard has ever been exposed publicly. ]]>

T08 Β· Insecure Dependencies

Error
Location
README.md:203
Finding
Unsafe Dependency Instructions Create Package-Substitution and Mutable Supply-Chain Risk<![CDATA[ ## Vulnerability Details **File Location**: `README.md:203-211` **Vulnerability Type**: Unpinned and misleading dependency installation **Risk Level**: High ### Vulnerable Code ```bash git clone https://github.com/lukmanc405/neko-futures-trader.git cd neko-futures-trader ``` ```bash pip install requests hmac hashlib ``` ### Technical Analysis The installation instructions retrieve mutable code from a personal Git repository without pinning a reviewed commit, release tag, or artifact digest. Future repository changes can therefore alter the effective code installed by users after an audit. The command also asks pip to install packages named `hmac` and `hashlib`, although both are Python standard-library modules and should not be installed from a public package registry. This creates package-substitution or dependency-confusion exposure: a similarly named registry package may be selected and its installation or runtime code may execute with the installer’s privileges. `requests` is also unpinned and lacks hash verification, preventing reproducible and integrity-checked installation. ### Attack Path 1. A user follows the documented installation procedure. 2. The Git repository content changes after review, or a malicious/untrusted package is published under one of the unnecessary standard-library names. 3. `git clone` or pip retrieves the changed component. 4. Package build hooks, installation logic, or imported runtime code executes under the user account running the installation. 5. The malicious component gains access to the same environment and files as the trading service, potentially including `.env` credentials. ### Impact Assessment Successful exploitation can result in arbitrary code execution with the installer’s privileges. Because this project handles Binance trading credentials and Telegram tokens, supply-chain compromise could lead to credential theft, unauthorized trading, file access, or additional malware installation. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `hmac` and `hashlib` from pip installation instructions; import them only from Python’s standard library. 2. Define required third-party dependencies in a lock file with exact versions and cryptographic hashes. 3. Install with hash enforcement, such as `pip install --require-hashes -r requirements.txt`. 4. Reference a reviewed release or immutable Git commit rather than an unpinned repository head. 5. Publish and verify release checksums or signed attestations. 6. Run installation in an isolated virtual environment under a non-privileged account. 7. Add automated dependency scanning and provenance verification to the release process. ]]>

T09 Β· Insecure Skill Coding Practices

Error
Location
price-monitor.py:270
Finding
Duplicated Position-Management Logic Can Over-Close or Reverse Leveraged Positions<![CDATA[ ## Vulnerability Details **File Location**: `price-monitor.py:270-576` **Vulnerability Type**: Unsafe duplicated order execution and stale position quantities **Risk Level**: Critical ### Vulnerable Code ```python def check_multi_tp(symbol, side, entry, current, position_amt, original_amt): """Check for multi-TP levels and close partial positions""" if side == 'LONG': profit_pct = ((current - entry) / entry) * 100 else: profit_pct = ((entry - current) / entry) * 100 remaining_pct = (abs(position_amt) / original_amt) * 100 if original_amt > 0 else 0 if profit_pct >= tp3 and remaining_pct > 0: close_amt = abs(position_amt) close_side = 'SELL' if side == 'LONG' else 'BUY' result = close_position(symbol, close_side, close_amt) ``` The first execution block begins with: ```python original_amt = abs(amt) # Store original amount for Multi-TP calculation check_multi_tp(symbol, side, entry, current, amt, original_amt) ``` The multi-TP, trailing-TP, stop-loss, and take-profit logic is then repeated later in the same loop: ```python original_amt = abs(amt) # Store original amount for Multi-TP calculation check_multi_tp(symbol, side, entry, current, amt, original_amt) ``` Orders are submitted without a reduce-only constraint: ```python def close_position(symbol, side, quantity): ts = int(time.time() * 1000) params = f'symbol={symbol}&side={side}&type=MARKET&quantity={quantity}&timestamp={ts}' r = requests.post(f'https://fapi.binance.com/fapi/v1/order?{params}&signature={get_sig(params)}', headers={'X-MBX-APIKEY': API_KEY}, timeout=15) return r.json() ``` ### Technical Analysis The same multi-TP, trailing, stop-loss, and take-profit execution logic appears twice in one position-processing iteration. A successful first order does not consistently terminate processing or refresh the current Binance position before the duplicate block executes. In addition, ...[truncated 1604 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the duplicated position-management block and maintain one deterministic state machine per position. 2. Persist the original position quantity and completed TP stages instead of resetting `original_amt` on every iteration. 3. Refresh position amount and order status from Binance after every successful fill. 4. Set `reduceOnly=true` for all quantity-based close and partial-close orders. 5. Return or continue immediately after a successful full close. 6. Use exchange-provided quantity precision and step-size normalization for every partial order. 7. Make order handling idempotent by recording client order IDs and completed actions. 8. Add tests covering partial fills, duplicate loop execution, stale quantities, network retries, and reverse-position prevention. 9. Prefer exchange-native protective orders with explicit reconciliation rather than simultaneously operating multiple competing close paths. ]]>

T09 Β· Insecure Skill Coding Practices

Error
Location
price-monitor.py:374
Finding
Missing Cached SL/TP State Disables Position Monitoring<![CDATA[ ## Vulnerability Details **File Location**: `price-monitor.py:374-387` **Vulnerability Type**: Use of uninitialized risk-control values **Risk Level**: High ### Vulnerable Code ```python # Get SL/TP from saved data, or calculate from ATR pos_data = saved_data.get(symbol, {}) if pos_data and 'sl' in pos_data and 'tp1' in pos_data: # Use saved SL/TP from scanner sl_price = float(pos_data['sl']) tp_price = float(pos_data['tp1']) print(f" {symbol}: [SAVED] Entry={entry:.6f} Current={current:.6f} SL={sl_price:.6f} TP={tp_price:.6f}") # Check for Multi-TP levels (partial closes) original_amt = abs(amt) # Store original amount for Multi-TP calculation check_multi_tp(symbol, side, entry, current, amt, original_amt) # Check for trailing TP - activate when profit > configured % try: trail_thresh = MIN_PROFIT_TRAILING_TP if 'MIN_PROFIT_TRAILING_TP' in dir() else 3.0 except: trail_thresh = 3.0 new_trailing_tp = should_activate_trailing_tp(entry, current, tp_price, side, trail_percent=trail_thresh) ``` ### Technical Analysis `sl_price` and `tp_price` are assigned only when the local JSON cache contains both expected fields. If a live Binance position was opened manually, the cache was deleted or corrupted, or a previous write failed, these variables remain uninitialized. The code nevertheless passes `tp_price` to `should_activate_trailing_tp` and later uses both variables in SL/TP comparisons. Python raises `UnboundLocalError`. The broad outer exception catches the error, prints it, and delays until the next loop, so the same unmanaged position can fail repeatedly. The documented ATR fallback occurs later and is not reached before the first use. ### Attack Path 1. A Binance futures position exists without a matching complete entry in `.positions_sl_tp.json`. 2. The monitor reads an empty or incomplete `pos_data` object. 3. It skips initialization of `sl_price` and `tp_price`. 4. The trailing-TP call references `tp_price`, raising ...[truncated 551 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Initialize `sl_price` and `tp_price` before any use. 2. If cached values are unavailable, immediately calculate validated ATR-based fallback values before invoking any TP/SL logic. 3. Treat malformed JSON or incomplete cache records as explicit errors and send an operator alert. 4. Reconcile every live Binance position with local state at startup. 5. Fail safely: either create exchange-native protective orders or suspend new trading when a live position cannot be protected. 6. Replace broad exception suppression with targeted handling and structured error reporting. 7. Add tests for missing files, empty records, corrupt JSON, manually opened positions, and partial cache writes. ]]>

T09 Β· Insecure Skill Coding Practices

Warning
Location
SKILL.md:71
Finding
Setup Instructions Print Credential File Contents<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:71-74` **Vulnerability Type**: Plaintext secret disclosure through operational instructions **Risk Level**: Medium ### Vulnerable Code ```bash # 3. Verify .env exists cat .env | head -3 ``` ### Technical Analysis The setup procedure verifies file existence by printing the first three lines of `.env`. This project documents `.env` as containing Binance API keys, a Binance secret, a Telegram bot token, and a Telegram channel identifier. Depending on variable order, the command can reveal highly sensitive credentials. This output may be captured in an AI-agent conversation, shell history context, terminal recording, CI/CD output, support transcript, centralized logging system, or screen recording. Reading secret values is unnecessary for checking whether the file exists. ### Attack Path 1. An operator or automated agent follows the documented setup instructions. 2. The first three lines of `.env` are printed in plaintext. 3. The terminal or agent execution output is retained in a transcript or log. 4. A person or service with access to that output obtains the exposed credentials. 5. The credentials are reused against Binance or Telegram, subject to their configured permissions. ### Impact Assessment Disclosure of a Binance secret may permit private API requests and unauthorized futures trading when combined with the associated API key. Disclosure of a Telegram bot token may permit bot impersonation, message sending, or access to bot-controlled workflows. The exact impact depends on which variables occupy the first three lines and on external API permission restrictions. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the command with a presence-only test: ```bash test -f .env && echo ".env exists" || echo ".env missing" ``` 2. If variable validation is required, print only variable names or redacted status values. 3. Never display secret values in agent output, CI logs, installation scripts, or troubleshooting documentation. 4. Add secret-scanning and output-redaction guidance to the project documentation. 5. Rotate credentials if this command has been executed in a recorded or shared environment. ]]>
Vulnerability Patterns
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (119)

Tainted flow: 'sig' from os.environ (line 31, credential/environment) β†’ requests.get (network output)

Critical
Category
Data Flow
Content
"""Use fapi/v2/positionRisk β€” has entryPrice, markPrice, unRealizedProfit."""
    ts  = int(time.time() * 1000)
    sig = hmac.new(SECRET.encode(), f'timestamp={ts}'.encode(), hashlib.sha256).hexdigest()
    r   = requests.get(
        f'https://fapi.binance.com/fapi/v2/positionRisk?timestamp={ts}&signature={sig}',
        headers={'X-MBX-APIKEY': API_KEY}, timeout=8
    )
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'sig2' from os.environ (line 60, credential/environment) β†’ requests.get (network output)

Critical
Category
Data Flow
Content
# Balance from account snapshot
    sig2 = hmac.new(SECRET.encode(), f'timestamp={ts}'.encode(), hashlib.sha256).hexdigest()
    r2   = requests.get(
        f'https://fapi.binance.com/fapi/v3/account?timestamp={ts}&signature={sig2}',
        headers={'X-MBX-APIKEY': API_KEY}, timeout=8
    )
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

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

Critical
Category
YARA Match
Content
s
from datetime import datetime, timedelta
from typing import Set, List, Dict

# Load env
script_dir = os.path.dirname(os.path.abspath(__file__))
env_file = os.path.join(script_dir, '.env')

if os.path.exists(env_file):
    with open(env_file) as f:
        for line in f:
            line = line.strip()
            if line and '=' in line:
                k, v = line.split('=', 1)
                os.environ[k] = v

API_KEY = os.environ.get('BINANCE_API_KEY', '')
BLOCKLIST_FILE = os.path.join(script_dir, '.delist_blocklist.json')

# Keywords that indicate delisting
DELIST_KEYWORDS = [
    'delist', 'removal', 'will be removed', 'will no longer',
    'εœζ­’δΊ€ζ˜“', 'δΈ‹ζžΆ', 'delisted', 'termination',
    'terminate', '停歒合约', '合约到期'
]

def load_blocklist() -> Set[str]:
    """Load blocked tokens from file"""
    try:
        with open(BLOCKLIST_FILE, 'r') as f:
            data = json.load(f)
            return set(data.get('tokens', []))
    except:
        return set()
Confidence
85% confidence
Finding
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Tainted flow: 'token' from os.environ.get (line 121, credential/environment) β†’ requests.post (network output)

Critical
Category
Data Flow
Content
msg += "\n_Automatically added to blocklist_"
    
    try:
        requests.post(f'https://api.telegram.org/bot{token}/sendMessage',
                    data={'chat_id': channel, 'text': msg, 'parse_mode': 'Markdown'},
                    timeout=10)
    except:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'API_KEY' from os.environ (line 23, credential/environment) β†’ requests.get (network output)

Critical
Category
Data Flow
Content
sig = get_sig(params)
    
    # Get account info
    r = requests.get(f'https://fapi.binance.com/fapi/v2/positionRisk?{params}&signature={sig}',
                   headers={'X-MBX-APIKEY': API_KEY}, timeout=15)
    positions = [p for p in r.json() if float(p.get('positionAmt', 0)) != 0]
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'API_KEY' from os.environ (line 23, credential/environment) β†’ requests.get (network output)

Critical
Category
Data Flow
Content
positions = [p for p in r.json() if float(p.get('positionAmt', 0)) != 0]
    
    # Get account balance
    r2 = requests.get(f'https://fapi.binance.com/fapi/v3/account?{params}&signature={sig}',
                    headers={'X-MBX-APIKEY': API_KEY}, timeout=15)
    acc = r2.json()
    balance = float(acc.get('totalMarginBalance', 0))
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

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

Critical
Category
YARA Match
Content
onfig import *
except ImportError:
    pass  # Use defaults

# === LOAD FROM ENV FILE ===
script_dir = os.path.dirname(os.path.abspath(__file__))
env_file = os.path.join(script_dir, '.env')

if os.path.exists(env_file):
    with open(env_file) as f:
        for line in f:
            line = line.strip()
            if line and '=' in line:
                k, v = line.split('=', 1)
                os.environ[k] = v

# === LOAD CONFIG ===
sys.path.insert(0, script_dir)
try:
    from config import *
except ImportError:
    pass

env_file = os.path.join(script_dir, '.env')

if env_file and os.path.exists(env_file):
    with open(env_file) as f:
        for line in f:
            line = line.strip()
            if line and not line.startswith('#') and '=' in line:
                key, value = line.split('=', 1)
                os.environ[key] = value

API_KEY = os.environ.get('BINANCE_API_KEY', '')
SECRET = os.environ.get('BINANCE_SECRET', '')
TELEGRAM_BOT_TOKEN = os.environ.get('TELEGRAM_B
Confidence
85% confidence
Finding
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Tainted flow: 'headers' from os.environ.get (line 123, credential/environment) β†’ requests.post (network output)

Critical
Category
Data Flow
Content
params = f'symbol={symbol}&side={close_side}&type=STOP_MARKET&stopPrice={new_sl}&workingType=CONTRACT_PRICE&closePosition=true&timestamp={ts}'
    sig = get_sig(params)
    try:
        r = requests.post(f'https://fapi.binance.com/fapi/v1/order?{params}&signature={sig}', 
                        headers=headers, timeout=15)
        return r.json()
    except:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'headers' from os.environ.get (line 123, credential/environment) β†’ requests.post (network output)

Critical
Category
Data Flow
Content
params = f'symbol={symbol}&side={close_side}&type=STOP_MARKET&stopPrice={new_sl}&workingType=CONTRACT_PRICE&closePosition=true&timestamp={ts}'
    sig = get_sig(params)
    try:
        r = requests.post(f'https://fapi.binance.com/fapi/v1/order?{params}&signature={sig}', 
                        headers=headers, timeout=15)
        return r.json()
    except:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'API_KEY' from os.environ.get (line 54, credential/environment) β†’ requests.get (network output)

Critical
Category
Data Flow
Content
def get_positions():
    ts = int(time.time() * 1000)
    params = f'timestamp={ts}'
    r = requests.get(f'https://fapi.binance.com/fapi/v2/positionRisk?{params}&signature={get_sig(params)}', 
                   headers={'X-MBX-APIKEY': API_KEY}, timeout=15)
    return [p for p in r.json() if float(p.get('positionAmt', 0)) != 0]
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'API_KEY' from os.environ.get (line 54, credential/environment) β†’ requests.get (network output)

Critical
Category
Data Flow
Content
def get_price(symbol):
    ts = int(time.time() * 1000)
    params = f'timestamp={ts}'
    r = requests.get(f'https://fapi.binance.com/fapi/v2/positionRisk?symbol={symbol}&{params}&signature={get_sig(params)}', 
                   headers={'X-MBX-APIKEY': API_KEY}, timeout=15)
    data = r.json()
    if isinstance(data, list) and len(data) > 0:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'API_KEY' from os.environ.get (line 54, credential/environment) β†’ requests.post (network output)

Critical
Category
Data Flow
Content
def close_position(symbol, side, quantity):
    ts = int(time.time() * 1000)
    params = f'symbol={symbol}&side={side}&type=MARKET&quantity={quantity}&timestamp={ts}'
    r = requests.post(f'https://fapi.binance.com/fapi/v1/order?{params}&signature={get_sig(params)}',
                     headers={'X-MBX-APIKEY': API_KEY}, timeout=15)
    return r.json()
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'TELEGRAM_BOT_TOKEN' from os.environ.get (line 56, credential/environment) β†’ requests.post (network output)

Critical
Category
Data Flow
Content
def send_telegram(msg):
    if TELEGRAM_BOT_TOKEN and TELEGRAM_CHANNEL:
        requests.post(f'https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage',
                    data={'chat_id': TELEGRAM_CHANNEL, 'text': msg, 'parse_mode': 'Markdown'})

def check_multi_tp(symbol, side, entry, current, position_amt, original_amt):
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'API_KEY' from os.environ.get (line 54, credential/environment) β†’ requests.get (network output)

Critical
Category
Data Flow
Content
for i in range(max_retries):
                        time.sleep(1)
                        check_params = f'orderId={order_id}&symbol={symbol}&timestamp={int(time.time() * 1000)}'
                        check_r = requests.get(f'https://fapi.binance.com/fapi/v1/order?{check_params}&signature={get_sig(check_params)}', 
                                              headers={'X-MBX-APIKEY': API_KEY}, timeout=15)
                        order_data = check_r.json()
                        status = order_data.get('status', '')
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

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

Critical
Category
YARA Match
Content
oad from the same directory as the script
script_dir = os.path.dirname(os.path.abspath(__file__))
env_file = os.path.join(script_dir, '.env')

if env_file and os.path.exists(env_file):
    with open(env_file) as f:
        for line in f:
            line = line.strip()
            if line and not line.startswith('#') and '=' in line:
                key, value = line.split('=', 1)
                os.environ[key] = value

# === LOAD CONFIG FROM config.py ===
try:
    from config import *
except ImportError:
    pass

# Load delisting blocklist
try:
    from delisting_monitor import is_token_blocked, get_blocklist, check_binance_delist_announcements
    DELISTING_CHECK = True
except ImportError:
    DELISTING_CHECK = False

# Default ATR multipliers if not loaded from config
try:
    ATR_MULTIPLIER_SL_HIGH
except NameError:
    ATR_MULTIPLIER_SL_HIGH = 2.0
try:
    ATR_MULTIPLIER_TP_HIGH
except NameError:
    ATR_MULTIPLIER_TP_HIGH = 4.0
try:
    ATR_MULTIPLIER_SL_NORMAL
except NameError
Confidence
85% confidence
Finding
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Tainted flow: 'url' from os.environ.get (line 459, credential/environment) β†’ requests.get (network output)

Critical
Category
Data Flow
Content
params['timestamp'] = int(time.time() * 1000)
        params['signature'] = get_signature('&'.join(f'{k}={v}' for k, v in params.items()))
    headers = {'X-MBX-APIKEY': API_KEY}
    r = requests.get(url, params=params, headers=headers, timeout=15)
    return r.json()

def binance_post(url, params):
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'url' from os.environ.get (line 459, credential/environment) β†’ requests.post (network output)

Critical
Category
Data Flow
Content
params['timestamp'] = int(time.time() * 1000)
    params['signature'] = get_signature('&'.join(f'{k}={v}' for k, v in params.items()))
    headers = {'X-MBX-APIKEY': API_KEY}
    r = requests.post(url, data=params, headers=headers, timeout=15)
    return r.json()

# === GET DATA ===
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'API_KEY' from os.environ.get (line 79, credential/environment) β†’ requests.get (network output)

Critical
Category
Data Flow
Content
ts = int(time.time() * 1000)
    params = "timestamp={}".format(ts)
    sig = get_signature(params)
    r = requests.get("https://fapi.binance.com/fapi/v3/account?{}&signature={}".format(params, sig),
                     headers={"X-MBX-APIKEY": API_KEY}, timeout=15)
    if r:
        try:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'API_KEY' from os.environ.get (line 79, credential/environment) β†’ requests.get (network output)

Critical
Category
Data Flow
Content
ts = int(time.time() * 1000)
    params = "timestamp={}".format(ts)
    sig = get_signature(params)
    r = requests.get("https://fapi.binance.com/fapi/v3/account?{}&signature={}".format(params, sig),
                     headers={"X-MBX-APIKEY": API_KEY}, timeout=15)
    if r:
        try:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'url' from os.environ.get (line 459, credential/environment) β†’ requests.get (network output)

Critical
Category
Data Flow
Content
"""Get current Open Interest for a symbol"""
    try:
        url = f'https://fapi.binance.com/fapi/v1/openInterest?symbol={symbol}'
        r = requests.get(url, timeout=10)
        data = r.json()
        return float(data.get('openInterest', 0))
    except:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'url' from os.environ.get (line 459, credential/environment) β†’ requests.get (network output)

Critical
Category
Data Flow
Content
"""Get current Open Interest for a symbol"""
    try:
        url = f'https://fapi.binance.com/fapi/v1/openInterest?symbol={symbol}'
        r = requests.get(url, timeout=10)
        data = r.json()
        return float(data.get('openInterest', 0))
    except:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'url' from os.environ.get (line 459, credential/environment) β†’ requests.get (network output)

Critical
Category
Data Flow
Content
"""Get current Open Interest for a symbol"""
    try:
        url = f'https://fapi.binance.com/fapi/v1/openInterest?symbol={symbol}'
        r = requests.get(url, timeout=10)
        data = r.json()
        return float(data.get('openInterest', 0))
    except:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'url' from os.environ.get (line 459, credential/environment) β†’ requests.get (network output)

Critical
Category
Data Flow
Content
"""Get current Open Interest for a symbol"""
    try:
        url = f'https://fapi.binance.com/fapi/v1/openInterest?symbol={symbol}'
        r = requests.get(url, timeout=10)
        data = r.json()
        return float(data.get('openInterest', 0))
    except:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'url' from os.environ.get (line 459, credential/environment) β†’ requests.get (network output)

Critical
Category
Data Flow
Content
"""Get current Open Interest for a symbol"""
    try:
        url = f'https://fapi.binance.com/fapi/v1/openInterest?symbol={symbol}'
        r = requests.get(url, timeout=10)
        data = r.json()
        return float(data.get('openInterest', 0))
    except:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'url' from os.environ.get (line 459, credential/environment) β†’ requests.get (network output)

Critical
Category
Data Flow
Content
def get_klines(symbol, interval='1h', limit=100):
    url = f'https://fapi.binance.com/fapi/v1/klines?symbol={symbol}&interval={interval}&limit={limit}'
    r = requests.get(url, timeout=15)
    return r.json()

def place_order_with_sl_tp(symbol, side, quantity, sl_price, tp_price):
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Static analysis

No suspicious patterns detected.