Back to skill

Security audit

Hummingbot

Security checks for vulnerabilities and agentic risk

Overview

This Hummingbot skill is trading-related, but it needs Review because it ships under-documented direct order placement and weak credential/API configuration practices that could affect real funds.

Review this before installing if it will connect to real exchange accounts. Use paper trading or testnet first, remove or avoid scripts/trade.py if direct order placement is not intended, disable withdrawals on exchange API keys, avoid passing secrets on the command line, set an explicit trusted local or HTTPS Hummingbot API URL, and change any default admin/admin credentials.

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

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/trade.py:22
Finding
Undocumented Direct Live-Order Trading Capability<![CDATA[ ## Vulnerability Details **File Location**: `scripts/trade.py:22-46` **Vulnerability Type**: Undeclared privileged financial operation **Risk Level**: High ### Vulnerable Code ```python async def cmd_order(args): order_type = args.type.upper() if order_type == "LIMIT" and args.price is None: print("Error: --price is required for limit orders") sys.exit(1) print(f"⚠️ Placing {order_type} {args.side.upper()} order:") print(f" {args.amount} {args.pair} on {args.connector} ({args.account})") if args.price: print(f" Price: {args.price}") confirm = input("Confirm? [y/N] ").strip().lower() if confirm != "y": print("Cancelled.") return async with client() as c: result = await c.trading.place_order( account=args.account, connector=args.connector, trading_pair=args.pair, side=args.side.upper(), amount=float(args.amount), order_type=order_type, price=float(args.price) if args.price else None, ) ``` ### Technical Analysis The Skill manifest advertises only the `connect`, `balance`, `create`, `start`, `stop`, `status`, and `history` commands. However, the packaged `trade.py` script exposes a direct order-placement interface capable of submitting market and limit orders to connected exchange accounts. This materially exceeds the declared command scope and gives the Skill a direct mechanism for committing user funds. Although the function asks for interactive confirmation, it has no notional-value ceiling, balance check, slippage protection, price-band policy, or account-specific authorization check. Market orders are especially sensitive because they are submitted without a price constraint. The confirmation prompt reduces accidental execution but does not establish a reliable security boundary in an Agent environment, where input may be generated or relayed automatically. ### Attack ...[truncated 1070 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove `trade.py` if direct discretionary trading is not part of the intended Skill. - Otherwise, explicitly document the direct order, cancellation, position, and trade-history commands in `SKILL.md`. - Require an approval mechanism that cannot be automatically satisfied by the same Agent initiating the transaction. - Display and approve the estimated quote notional, applicable leverage, expected fees, and maximum slippage before submission. - Reject non-finite, zero, negative, or policy-exceeding amounts and prices. - Add configurable per-order and per-day notional limits. - Default to limit orders and require an additional explicit authorization for market orders. - Enforce account, connector, and trading-pair allowlists. - Use exchange credentials restricted to required markets and permissions, with withdrawals disabled. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/hbot_client.py:17
Finding
Undeclared Working-Directory Environment File Loading<![CDATA[ ## Vulnerability Details **File Location**: `scripts/hbot_client.py:17-36` **Vulnerability Type**: Untrusted configuration discovery and API endpoint injection **Risk Level**: Medium ### Vulnerable Code ```python ENV_PATHS = [ "hummingbot-api/.env", os.path.expanduser("~/.hummingbot/.env"), ".env", ] def load_env(): """Load .env file — first match wins.""" for path in ENV_PATHS: if os.path.exists(path): with open(path) as f: for line in f: line = line.strip() if line and not line.startswith("#") and "=" in line: key, _, value = line.partition("=") os.environ.setdefault( key.strip(), value.strip().strip('"').strip("'"), ) return path return None ``` ### Technical Analysis The implementation loads `.env` from the current working directory, although `SKILL.md` only declares `./hummingbot-api/.env`, `~/.hummingbot/.env`, environment variables, and defaults. The current working directory may be controlled by the calling environment or may point to an unrelated project. If the two higher-priority files do not exist, a local `.env` can set `HUMMINGBOT_API_URL`, `API_USER`, and `API_PASS`, redirecting API operations to an unintended service. The loader also imports every key found in the file into `os.environ`, rather than limiting parsing to the three configuration values required by this Skill. This exceeds minimum necessary configuration access and can modify the behavior of imported dependencies. ### Attack Path 1. An attacker or untrusted project places a crafted `.env` in the directory from which the Skill is executed. 2. The expected `hummingbot-api/.env` and `~/.hummingbot/.env` files are absent. 3. `load_env()` selects the working-directory `.env`. 4. The file supplies an attacker-controlled `HUMMINGBOT_AP ...[truncated 702 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove implicit working-directory `.env` discovery. - If working-directory configuration is required, document it and require an explicit command-line option selecting the file. - Resolve configuration paths relative to a trusted installation root rather than the caller's current directory. - Parse only `HUMMINGBOT_API_URL`, `API_USER`, and `API_PASS`; do not import arbitrary keys. - Verify that configuration files are regular files owned by the expected user and are not group- or world-writable. - Reject symlinked configuration files where appropriate. - Validate the API scheme and host before creating the client. - Log which configuration source was selected without logging any credential values. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/history.py:28
Finding
Basic Authentication Credentials Can Be Sent over Plaintext HTTP to an Arbitrary Host<![CDATA[ ## Vulnerability Details **File Location**: `scripts/history.py:28-34`; configuration source at `scripts/hbot_client.py:48-58` **Vulnerability Type**: Plaintext credential transmission and unrestricted destination **Risk Level**: Medium ### Vulnerable Code ```python # scripts/hbot_client.py url = os.environ.get("HUMMINGBOT_API_URL", "http://localhost:8000") username = os.environ.get("API_USER") or os.environ.get("API_USER", "admin") password = os.environ.get("API_PASS") or os.environ.get("API_PASS", "admin") return (url, username, password) ``` ```python # scripts/history.py url_base, username, password = get_config() url = f"{url_base}{endpoint}" credentials = base64.b64encode(f"{username}:{password}".encode()).decode() headers = {"Authorization": f"Basic {credentials}"} req = urllib.request.Request(url, headers=headers) try: with urllib.request.urlopen(req, timeout=30) as resp: return json.loads(resp.read().decode()) ``` ### Technical Analysis The API base URL is accepted without scheme or host validation. The documented and implemented default uses plaintext HTTP. `history.py` constructs a standard Basic Authentication header by Base64-encoding `username:password`. Base64 is reversible encoding, not encryption. Consequently, when a non-loopback HTTP endpoint is configured, any party able to observe the connection can recover the API username and password. The pre-scan concern that the encoded credentials are printed or used as a covert stdout channel is not substantiated: the encoded value is placed in an HTTP header and is not printed. The actual risk is unrestricted transport of reusable credentials. ### Attack Path 1. `HUMMINGBOT_API_URL` is set to a remote URL using `http://`, whether through environment configuration or a selected `.env`. 2. The user invokes `history.py`, or another client operation using the same API configuration. 3. The script generates an Authorization header containing reversible `username:password` da ...[truncated 681 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Allow plaintext HTTP only when the parsed destination is a verified loopback address. - Require HTTPS for every non-loopback destination. - Validate the URL scheme, hostname, port, and absence of embedded user information before use. - Use trusted certificate validation and do not disable TLS verification. - Ensure Authorization headers are not forwarded to a different origin during redirects; preferably reject cross-origin redirects. - Prefer scoped, short-lived, revocable access tokens over reusable Basic Auth credentials. - Provide a server fingerprint or explicit host allowlist for sensitive deployments. - Avoid including response bodies verbatim in authentication-related error messages if the server is not trusted. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/hbot_client.py:41
Finding
Known Default Administrative Credentials Are Used When Configuration Is Missing<![CDATA[ ## Vulnerability Details **File Location**: `scripts/hbot_client.py:41-51` **Vulnerability Type**: Insecure default credentials and failure to fail closed **Risk Level**: Medium ### Vulnerable Code ```python def get_config(): """Return (url, username, password) from env. Accepts both new names (API_USER, API_PASS) and prefixed names (API_USER, API_PASS). """ load_env() url = os.environ.get("HUMMINGBOT_API_URL", "http://localhost:8000") username = os.environ.get("API_USER") or os.environ.get("API_USER", "admin") password = os.environ.get("API_PASS") or os.environ.get("API_PASS", "admin") return (url, username, password) ``` ### Technical Analysis When API credentials are absent, the client silently uses the publicly known `admin/admin` credential pair. The same defaults are documented in `SKILL.md`, making them predictable to any party who can reach a deployment that retains them. The duplicated `os.environ.get("API_USER")` and `os.environ.get("API_PASS")` expressions do not implement the documented compatibility with alternative prefixed names. They simply produce the default values when the corresponding variables are unset. For a trading administration API, silently falling back to known credentials is unsafe. Missing security configuration should cause startup to fail rather than creating the appearance of a configured authenticated client. ### Attack Path 1. A Hummingbot API deployment retains or accepts the `admin/admin` credentials. 2. The service becomes reachable by another local user, container, or network peer. 3. The attacker authenticates using the documented default pair. 4. The attacker invokes the API's available account, bot, or trading operations. ### Impact Assessment The exact impact depends on API exposure and server-side permissions. If the default account has broad administrative authority, compromise may include viewing portfolio data, managing exchange credentials, deploying or stop ...[truncated 201 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove the `admin/admin` fallback and fail closed when either credential is missing. - Generate high-entropy credentials during initial deployment. - Refuse to operate if known default credentials are detected. - Store secrets in a protected secret manager or a file restricted to the owning user. - Use separate, least-privilege credentials for read-only monitoring and trading administration. - Add authentication rate limiting and account lockout controls on the API server. - Correct the duplicated environment-variable expressions if alternative variable names were intended. ]]>

T08 · Insecure Dependencies

Note
Location
SKILL.md:6
Finding
Security-Sensitive API Client Dependency Is Not Reproducibly Pinned<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:6` and `SKILL.md:87` **Vulnerability Type**: Unpinned third-party dependency **Risk Level**: Low ### Vulnerable Code ```yaml metadata: author: hummingbot requires: hummingbot-api-client>=1.2.8 ``` ```bash pip3 install hummingbot-api-client ``` ### Technical Analysis The Hummingbot API client executes in the same Python process as the Skill and receives the API URL, username, and password. It is therefore a security-sensitive dependency with access to authentication material and financial management operations. The dependency declaration only specifies a lower version boundary, and the installation instruction does not provide a lockfile, package hash, exact version, or package-index restriction. A future version satisfying `>=1.2.8` can be installed without further review, making builds non-reproducible. No evidence shows that the named package is currently malicious. This finding concerns exposure to future supply-chain compromise or incompatible releases. ### Attack Path 1. A future compromised, malicious, or incompatible package version is published under the expected package name. 2. The version satisfies the `>=1.2.8` constraint. 3. A user follows the documented `pip3 install hummingbot-api-client` command. 4. Python imports the installed package from `scripts/hbot_client.py`. 5. Package code executes with the Skill process's permissions and receives Hummingbot API credentials. 6. A compromised package could misuse credentials or alter account and trading operations. ### Impact Assessment A compromised dependency could access all secrets and API operations available to the Skill process. This includes Hummingbot API authentication data and potentially exchange credential management or financial operations. The likelihood is lower than the configuration vulnerabilities because exploitation requires a compromised distribution channel or package release. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Pin the dependency to an exact audited version. - Maintain a lockfile containing hashes for all direct and transitive dependencies. - Install with hash verification, such as `pip install --require-hashes`. - Restrict package resolution to the intended package index. - Review dependency updates before changing the pinned version. - Use an isolated virtual environment with only required packages. - Add software composition analysis and provenance verification to the release process. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • 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 (39)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description says this skill faithfully reproduces core Hummingbot CLI trading commands such as connect, balance, create, start, stop, status, and history. However, the provided code chunk is focused on account administration and credential management, not trading workflow execution. While listing connectors and adding credentials is somewhat adjacent to a 'connect' concept, the script does not expose the declared command set and instead adds undeclared capabilities around account creation and credential deletion/storage. This is a material description-behavior mismatch because the primary purpose differs from the declared trading CLI replication.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description says the skill reproduces key Hummingbot CLI commands for core trading workflows, naming connect, balance, create, start, stop, status, and history. The supplied code does not implement those account/trading workflow commands. Instead, it manages bot lifecycle operations: list, deploy, stop, status, logs, controllers, and scripts. While there is partial overlap on stop and status, the primary purpose is materially different: bot deployment and inspection rather than general Hummingbot CLI command reproduction. It also exposes undeclared capabilities such as fetching logs and listing controllers/scripts.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The declared description says the skill faithfully reproduces multiple Hummingbot CLI commands through the API as a core trading workflow agent. This code chunk does not support that broad purpose. It is limited to a create.py helper that lists controllers/scripts/configs and partially handles controller config creation. There is no evidence here of trading workflow commands like connect, balance, start, stop, status, or history. Additionally, even within 'create', functionality is partial: script creation is not implemented, and controller creation mostly checks template existence and prints a config path rather than fully creating/configuring a bot. This is a material description-to-behavior mismatch due to substantially narrower and different actual functionality.

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding
The declared purpose describes a skill that reproduces core Hummingbot CLI commands through the API. The supplied code does not perform those commands; instead, it is a utility module for loading API credentials from local .env files/environment variables, instantiating the API client, and formatting table output. While this helper could support such a skill, the code chunk itself does not match the declared primary functionality. Therefore this chunk is a description/behavior mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding
The declared description presents the skill as a broader Hummingbot CLI replica covering multiple core commands. The supplied code chunk, however, is narrowly focused on retrieving and displaying trading history for a bot, with an optional summary view. It uses the Hummingbot API consistently with the description and does not show unrelated or suspicious extra behavior, but it materially underdelivers relative to the declared scope. Therefore this is a description-to-behavior mismatch for this chunk because the actual primary purpose is just history retrieval, not the full set of CLI workflows described.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
There is a clear description-behavior mismatch. The declared description says this skill faithfully reproduces core Hummingbot CLI commands related to account connection, balances, strategy creation, bot lifecycle control, and history. The supplied code instead defines a separate utility for market data access only. Its subcommands are price, orderbook, candles, and funding, all calling c.market_data APIs. No code handles account connectivity, balances, creating strategies, starting/stopping bots, status checks, or history retrieval. This is not a minor implementation detail; it is a materially different primary purpose and adds undeclared capabilities while omitting the declared ones.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
There is a clear description-behavior mismatch. The declared purpose says the skill faithfully reproduces core Hummingbot CLI commands related to connection management, balances, strategy creation, bot lifecycle control, status, and history. However, the supplied code chunk only provides portfolio management/reporting functionality: querying overall state, total value, distribution, and token-specific holdings. These are materially different capabilities and do not correspond to the declared command set. While both relate to Hummingbot APIs, the primary purpose of the code is portfolio analysis rather than reproducing the stated Hummingbot CLI trading workflow commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The description says the skill reproduces multiple Hummingbot CLI commands and focuses on V1 core trading workflows. This code only covers a narrow subset: starting bots and listing running bots. It does not implement connect, balance, create, stop, status, or history in this chunk. More importantly, the code repeatedly states that the Hummingbot API supports V2 strategies only and that V1 strategies must use the traditional client, which materially conflicts with the declared V1 focus. Therefore, the code behavior is not accurately represented by the declared description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The description says the skill reproduces a specific set of Hummingbot CLI commands: connect, balance, create, start, stop, status, and history. This code chunk instead provides a different trading interface focused on direct order management and positions: order, orders, cancel, positions, and history. While both are related to Hummingbot trading workflows and the use of the Hummingbot API is consistent, the declared description materially misrepresents the actual command surface and capabilities of this code. The mismatch is both by omission of undeclared capabilities (order placement/cancellation, positions) and by absence of several prominently declared capabilities (connect, balance, create, start, stop, status).

Missing User Warnings

High
Confidence
96% confidence
Finding
The skill documents commands that can start live trading bots and close positions, but it does not prominently warn that these actions can create real financial loss, market exposure, or irreversible executions. In this context, omission of risk warnings is more dangerous because the skill is specifically aimed at automated trading workflows where agent or user mistakes can immediately trigger loss-causing actions.

Credential Access

High
Category
Privilege Escalation
Content
Shared Hummingbot API client helper.

Auth priority:
  1. ./hummingbot-api/.env  (API_USER, API_PASS)
  2. ~/.hummingbot/.env
  3. .env (current directory)
  4. Environment variables
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
Shared Hummingbot API client helper.

Auth priority:
  1. ./hummingbot-api/.env  (API_USER, API_PASS)
  2. ~/.hummingbot/.env
  3. .env (current directory)
  4. Environment variables
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
Shared Hummingbot API client helper.

Auth priority:
  1. ./hummingbot-api/.env  (API_USER, API_PASS)
  2. ~/.hummingbot/.env
  3. .env (current directory)
  4. Environment variables
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
Shared Hummingbot API client helper.

Auth priority:
  1. ./hummingbot-api/.env  (API_USER, API_PASS)
  2. ~/.hummingbot/.env
  3. .env (current directory)
  4. Environment variables
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
ENV_PATHS = [
    "hummingbot-api/.env",
    os.path.expanduser("~/.hummingbot/.env"),
    ".env",
]
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
ENV_PATHS = [
    "hummingbot-api/.env",
    os.path.expanduser("~/.hummingbot/.env"),
    ".env",
]
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
ENV_PATHS = [
    "hummingbot-api/.env",
    os.path.expanduser("~/.hummingbot/.env"),
    ".env",
]
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill exposes capabilities that involve reading environment/config secrets and interacting with a local API over the network, but it does not declare any tool scope such as permissions or allowed-tools. This weakens least-privilege controls and makes it harder for a host agent or reviewer to understand that the skill can access credentials and trigger trading-related API actions.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill instructs users to provide exchange API keys and also documents fallback default API credentials of admin/admin for the Hummingbot API without a strong warning. In a trading context, this increases the chance of credential leakage, insecure deployment, or unauthorized access to a local trading service that can manage exchange connections and bot actions.

Description-Behavior Mismatch

Medium
Confidence
86% confidence
Finding
The manifest says the skill faithfully reproduces a limited set of Hummingbot CLI commands such as connect, balance, create, start, stop, status, and history via the Hummingbot API. This file instead documents an advanced PMM Mister controller with detailed trading-strategy configuration, leverage, position management, and risk controls, indicating the skill surface includes strategy-specific guidance beyond the manifest's stated core command-reproduction scope.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The documentation promotes leveraged perpetual trading and automated stop-loss/take-profit behavior without an explicit risk disclosure. In a trading skill context, omission of clear warnings can lead users to apply high-risk strategies without understanding liquidation, slippage, and rapid-loss scenarios, increasing the chance of financial harm.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The aggressive example normalizes 20x leverage and rapid-refresh scalping settings without any suitability warning or guardrails. In this skill context, examples are likely to be copied directly by users, so presenting extreme leverage as a ready-to-use template materially increases the risk of severe financial losses or liquidation.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The documentation describes an automated market-making controller that continuously places, cancels, and refreshes live exchange orders, but it does not prominently warn users that enabling it can immediately affect real balances, create unintended trades, and incur fees. In a trading skill context, omission of this warning increases the chance that a user treats the controller as informational rather than fund-impacting automation, which can lead to financial loss from misconfiguration or accidental live deployment.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The usage examples explicitly encourage users to pass API keys, secret keys, and passphrases on the command line. Command-line arguments are commonly exposed through shell history, process listings, audit logs, and terminal recording, which can lead to credential disclosure and downstream account compromise.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
This script implements adding and removing exchange API credentials, which goes beyond the manifest’s described CLI scope of trading workflows such as connect, balance, create, start, stop, status, and history. Scope expansion around credential management is security-relevant because it introduces secret-handling capabilities that may not be expected, reviewed, or constrained by users and operators.

Static analysis

No suspicious patterns detected.