Back to skill

Security audit

LP Agent

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent Hummingbot liquidity-trading purpose, but it needs Review because it can handle wallet keys and deploy mutable trading infrastructure with unsafe defaults and broad local effects.

Install only if you are comfortable granting this skill control over local Hummingbot trading infrastructure and wallet import workflows. Use a dedicated low-value wallet, change default credentials before exposing any service, keep API/Gateway endpoints on localhost or trusted HTTPS only, avoid --defaults for real funds, review the deploy script before running it as root, and prefer --no-open for generated reports from untrusted data.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • 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
Findings (8)

T07 · Tool Hijacking and Spoofing

Error
Location
scripts/deploy_hummingbot_api.sh:152
Finding

Global replacement of the sudo command with an unauthenticated wrapper

Content
View full analysis
/dev/null; then echo -e '#!/bin/bash\nwhile [[ "$1" == *=* ]]; do export "$1"; shift; done\nexec "$@"' > /usr/local/bin/sudo chmod +x /usr/local/bin/sudo fi ``` ### Technical Analysis When installation runs as root in an environment without `sudo`, the script creates `/usr/local/bin/sudo`. This replacement does not implement real `sudo` authentication, authorization, environment filtering, user switching, or command-policy enforcement. It simply exports assignment-style arguments and executes the remaining command under the current process identity. Writing a spoofed executable into a globally trusted command path exceeds the privileges necessary to deploy Hummingbot. The modification is also not disclosed in the Skill documentation. ### Attack Path 1. Run `deploy_hummingbot_api.sh install` as root in a container or environment without an existing `sudo`. 2. The installer writes the wrapper to `/usr/local/bin/sudo`. 3. A later setup script, administrator, or application resolves `sudo` through `PATH`. 4. The wrapper executes the supplied command directly as root without normal `sudo` policy checks. 5. Attacker-controlled arguments passed through such a call receive root-level execution. ### Impact Assessment This can affect every process that resolves `/usr/local/bin/sudo` before the legitimate binary. It can bypass expected privilege boundaries, create incorrect security assumptions, and execute commands with root privileges. The replacement remains on the filesystem after the installer exits. ]]>
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/check_api.sh:16
Finding

Credential files are executed as arbitrary shell code

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/deploy_hummingbot_api.sh:232
Finding

Environment-controlled reset path permits unintended recursive deletion

Content
View full analysis
/dev/null || true cd ~ rm -rf "$INSTALL_DIR" ok "Hummingbot API removed" } ``` ### Technical Analysis `INSTALL_DIR` is controlled by the `HUMMINGBOT_API_DIR` environment variable and is not canonicalized, restricted, or validated as a Hummingbot installation. The function also changes to the user's home directory before deleting the path. Consequently, a relative `INSTALL_DIR` is resolved against a different directory during deletion than during the initial existence check and `cd`. An absolute attacker-selected value can target an arbitrary existing directory, while relative-path confusion can remove an unrelated directory under the user's home. ### Attack Path 1. Set `HUMMINGBOT_API_DIR` to a sensitive existing directory or a crafted relative path. 2. Invoke `deploy_hummingbot_api.sh reset`. 3. The script checks that the selected directory exists and enters it. 4. It changes the current directory to the user's home. 5. `rm -rf "$INSTALL_DIR"` recursively removes the selected or reinterpreted path without confirmation. ### Impact Assessment The vulnerability can delete arbitrary directories writable by the invoking user. When run as root, the scope can extend to system directories and application data. The Docker command also removes associated volumes, potentially destroying databases and trading records. ]]>
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/add_wallet.py:53
Finding

API credentials and wallet private keys can be transmitted to an arbitrary plaintext endpoint

Content
View full analysis
dict: """Make authenticated API request.""" config = get_api_config() url = f"{config['url']}{endpoint}" credentials = base64.b64encode(f"{config['user']}:{config['password']}".encode()).decode() headers = { "Authorization": f"Basic {credentials}", "Content-Type": "application/json", } body = json.dumps(data).encode() if data else None req = urllib.request.Request(url, data=body, headers=headers, method=method) try: with urllib.request.urlopen(req, timeout=60) as resp: return json.loads(resp.read().decode()) ``` ```python data = { "chain": args.chain, "private_key": private_key, } print(f"Adding {args.chain} wallet...") result = api_request("POST", "/accounts/gateway/add-wallet", data) ``` ### Technical Analysis The scripts accept `HUMMINGBOT_API_URL` without restricting its host or requiring HTTPS. Every request sends the API username and password in a Basic Authorization header. During wallet import, the wallet private key is also placed in the request body. Base64 is standard Basic Authentic ...[truncated 1284 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/deploy_hummingbot_api.sh:159
Finding

Installer creates services with documented default credentials

Content
View full analysis
.env << EOF USERNAME=admin PASSWORD=admin CONFIG_PASSWORD=admin DEBUG_MODE=false BROKER_HOST=hummingbot-broker BROKER_PORT=1883 BROKER_USERNAME=admin BROKER_PASSWORD=password DATABASE_URL=postgresql+asyncpg://hbot:hummingbot-api@hummingbot-postgres:5432/hummingbot_api BOTS_PATH=/hummingbot-api/bots EOF ``` The Skill documentation also states that the default credentials are `admin/admin`. ### Technical Analysis The non-interactive installation path writes several static, publicly documented credentials. These credentials protect infrastructure capable of importing wallets and initiating automated financial operations. Security therefore depends entirely on the services never becoming reachable outside a trusted local boundary. The defaults also include predictable broker and database credentials, increasing the blast radius if container networking, port publication, or host firewall configuration changes. ### Attack Path 1. Deploy the API using `install --defaults`, from a non-interactive environment, or from a detected container. 2. The installer writes the predictable credentials. 3. The API, broker, or database becomes reachable because of Docker port publication, reverse proxying, host-network mode, or firewall configuration. 4. An attacker authenticates using the documented default values. 5. The attacker accesses or manipulates the exposed trading infrastructure. ### Impact Assessment Depending on exposed interfaces, an attacker may obtain API administration, bot deployment, executor control, Gateway management, configuration access, or database/broker access. This could result in unauthorized trades, service disruption, data modification, or disclosure of connected- ...[truncated 24 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/visualize_lp_executor.py:223
Finding

Unescaped API and database values permit JavaScript execution in automatically opened reports

Content
View full analysis
{label}' f'{value}') ``` ```python table_rows = "".join([ row("Executor ID", f'{eid}'), row("Account", account), row("Controller", controller or "—"), row("Connector", connector), row("Trading Pair", pair, "#e8eaed"), ``` ```html LP Executor — {pair} ...

{pair} — LP Executor

ID: {eid} · {connector} · {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
``` The SQLite report embeds serialized values directly inside an executable script element: ```python def generate_html(chart_data: list[dict], meta: dict) -> str: """Build a self-contained HTML file with the dashboard.""" data_json = json.dumps(chart_data) meta_json = json.dumps(meta) return f""" ... ``` Generated reports are written and then opened through `webbrowser.open(...)` unless the user disables that behavior. ### Technical Analysis API-controlled fields such as pair, account, controller, connector, executor ID, pool address, and position address are inserted into HTML body, title, and attribute contexts without escaping. An attacker-controlled value containing markup can therefore create new HTML or script elements. For the SQLite dashboa ...[truncated 1346 chars]
Remediation
View remediation
`, `&`, Unicode line separators, and especially any `` sequence. - Prefer an inert `

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/deploy_hummingbot_api.sh:137
Finding

Unpinned remote repository is fetched and immediately executed

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/setup_gateway.sh:45
Finding

Mutable container tags and third-party CDN scripts are executed without integrity pinning

Content
View full analysis
``` ```html ``` Other management scripts default to mutable `latest` or `development` image tags. ### Technical Analysis Docker tags such as `latest` and `development` do not identify immutable artifacts. The same command can retrieve different container contents over time. Generated reports also execute CDN-hosted JavaScript without integrity hashes, making report behavior dependent on externally hosted content at viewing time. These dependencies are functionally related to the Skill, but the absence of immutable pinning and integrity verification creates an avoidable supply-chain risk. ### Attack Path 1. A container registry account, image publishing pipeline, CDN, or up ...[truncated 678 chars]
Remediation
View remediation
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (97)

Tainted flow: 'req' from os.environ.get (line 42, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/get_meteora_pool.py (reported line 32)May include surrounding context.

python
"Accept": "application/json",
        "User-Agent": "Mozilla/5.0 (compatible; hummingbot-skills/1.0)",
    })
    with urllib.request.urlopen(req, timeout=30) as resp:
        return json.loads(resp.read().decode())

Tainted flow: 'req' from os.environ.get (line 42, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

The Gateway request URL is built from GATEWAY_HOST and GATEWAY_PORT environment variables, then fetched over plain HTTP. In a skill that may run in varied agent environments, an attacker who can influence environment configuration could redirect requests to an unintended internal or external service, causing SSRF-style behavior, data leakage about queried pool addresses, or interaction with an untrusted gateway.

Content

Scanner excerpt · scripts/get_meteora_pool.py (reported line 44)May include surrounding context.

python
url = f"http://{GATEWAY_HOST}:{GATEWAY_PORT}/connectors/meteora/clmm/pool-info?network=mainnet-beta&poolAddress={address}"
    req = urllib.request.Request(url, headers={"Accept": "application/json"})
    try:
        with urllib.request.urlopen(req, timeout=10) as resp:
            return json.loads(resp.read().decode()), None
    except urllib.error.URLError as e:
        return None, f"Gateway not reachable at {GATEWAY_HOST}:{GATEWAY_PORT}"

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill generates local HTML reports, may open a browser, and fetches external market data from KuCoin, none of which is clearly disclosed by the top-level description. Undisclosed external requests and local file/browser actions widen the trust boundary and can surprise users in environments where outbound traffic or local artifact creation is sensitive.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill generates local HTML reports, may open a browser, and fetches external market data from KuCoin, none of which is clearly disclosed by the top-level description. Undisclosed external requests and local file/browser actions widen the trust boundary and can surprise users in environments where outbound traffic or local artifact creation is sensitive.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill generates local HTML reports, may open a browser, and fetches external market data from KuCoin, none of which is clearly disclosed by the top-level description. Undisclosed external requests and local file/browser actions widen the trust boundary and can surprise users in environments where outbound traffic or local artifact creation is sensitive.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill generates local HTML reports, may open a browser, and fetches external market data from KuCoin, none of which is clearly disclosed by the top-level description. Undisclosed external requests and local file/browser actions widen the trust boundary and can surprise users in environments where outbound traffic or local artifact creation is sensitive.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill generates local HTML reports, may open a browser, and fetches external market data from KuCoin, none of which is clearly disclosed by the top-level description. Undisclosed external requests and local file/browser actions widen the trust boundary and can surprise users in environments where outbound traffic or local artifact creation is sensitive.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill generates local HTML reports, may open a browser, and fetches external market data from KuCoin, none of which is clearly disclosed by the top-level description. Undisclosed external requests and local file/browser actions widen the trust boundary and can surprise users in environments where outbound traffic or local artifact creation is sensitive.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill generates local HTML reports, may open a browser, and fetches external market data from KuCoin, none of which is clearly disclosed by the top-level description. Undisclosed external requests and local file/browser actions widen the trust boundary and can surprise users in environments where outbound traffic or local artifact creation is sensitive.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill generates local HTML reports, may open a browser, and fetches external market data from KuCoin, none of which is clearly disclosed by the top-level description. Undisclosed external requests and local file/browser actions widen the trust boundary and can surprise users in environments where outbound traffic or local artifact creation is sensitive.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill generates local HTML reports, may open a browser, and fetches external market data from KuCoin, none of which is clearly disclosed by the top-level description. Undisclosed external requests and local file/browser actions widen the trust boundary and can surprise users in environments where outbound traffic or local artifact creation is sensitive.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The skill generates local HTML reports, may open a browser, and fetches external market data from KuCoin, none of which is clearly disclosed by the top-level description. Undisclosed external requests and local file/browser actions widen the trust boundary and can surprise users in environments where outbound traffic or local artifact creation is sensitive.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill generates local HTML reports, may open a browser, and fetches external market data from KuCoin, none of which is clearly disclosed by the top-level description. Undisclosed external requests and local file/browser actions widen the trust boundary and can surprise users in environments where outbound traffic or local artifact creation is sensitive.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill generates local HTML reports, may open a browser, and fetches external market data from KuCoin, none of which is clearly disclosed by the top-level description. Undisclosed external requests and local file/browser actions widen the trust boundary and can surprise users in environments where outbound traffic or local artifact creation is sensitive.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 603)May include surrounding context.

md
python scripts/visualize_lp_executor.py --id <executor_id>

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 645)May include surrounding context.

md
python scripts/visualize_lp_executor.py --id <executor_id>

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 655)May include surrounding context.

md
python scripts/visualize_lp_executor.py --id <executor_id>

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 721)May include surrounding context.

md
python scripts/visualize_lp_executor.py --id <executor_id>

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 722)May include surrounding context.

md
python scripts/visualize_lp_executor.py --id <executor_id>

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 723)May include surrounding context.

md
python scripts/visualize_lp_executor.py --id <executor_id>

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 803)May include surrounding context.

md
python scripts/visualize_lp_executor.py --id <executor_id>

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · SKILL.md (reported line 609)May include surrounding context.

The executor ID is returned when the executor is created (printed as Executor ID: <id>). If the user doesn't have it handy, fetch it from the API:

bash
curl -s -u admin:admin -X POST http://localhost:8000/executors/search \
  -H "Content-Type: application/json" \
  -d '{"type":"lp_executor"}' | python3 -c "
import json,sys

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 653)May include surrounding context.

md
| `scripts/visualize_lp_positions.py` | Generate HTML dashboard from position events (SQLite/bot-container based) |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 663)May include surrounding context.

md
| `scripts/visualize_lp_positions.py` | Generate HTML dashboard from position events (SQLite/bot-container based) |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 666)May include surrounding context.

md
| `scripts/visualize_lp_positions.py` | Generate HTML dashboard from position events (SQLite/bot-container based) |

Static analysis

No suspicious patterns detected.