Back to skill

Security audit

Vantage — HL Autonomous Trading Agent

Security checks for vulnerabilities and agentic risk

Overview

This is a real autonomous crypto trading tool, but it needs review because live risk checks can use a wallet address that is not proven to match the private key signing real orders.

Install only after reviewing the live-trading risks. Use paper mode first, keep only limited funds under the signing key, protect the .env private key, disable OpenAI fallback if trading context should stay local, update flagged dependencies, and do not run live mode until the software enforces that the wallet address used for balance/position checks matches the private key that signs orders.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
src/index.js:170
Finding

Live Trading Risk Controls Are Not Bound to the Signing Account

Content
View full analysis

Vulnerability Details

File Location: src/index.js:170, 219-234; related code in src/sizing.js:27-37 and src/trader.js:228-286
Vulnerability Type: Account identity mismatch in financial risk controls
Risk Level: High

Vulnerable Code

The autonomous loop obtains the account used for position checks and position sizing from a configurable address:

js
const walletAddress = process.env.HYPERLIQUID_WALLET_ADDRESS || '';
js
// Enforce max open positions (live only)
if (!isPaper && walletAddress) {
  const openPos = await getPositions(walletAddress);
  if (openPos.length >= maxOpenPos) {
    console.log(`  Skip ${signal.coin}: ${maxOpenPos} positions open`);
    continue;
  }
}

// Position sizing
let sizeUsd;
if (isPaper) {
  sizeUsd = Math.min(signal.confidence * kellyFraction * 10_000, maxPosUsd);
} else {
  try {
    const { calculatePositionSize } = require('./sizing');
    const sizing = await calculatePositionSize(signal.confidence, walletAddress);
    sizeUsd = sizing.sizeUsd;
    console.log(`  Sizing: $${sizeUsd} (${sizing.kellySizePct}% Kelly of $${sizing.balance})`);
  } catch (err) {
    console.warn(`  Sizing failed: ${err.message} -- aborting trade`);
    continue;
  }
}

The sizing module queries the balance of that supplied address:

js
async function calculatePositionSize(confidence, walletAddress) {
  if (confidence <= 0 || confidence > 1) {
    throw new Error(`Invalid confidence value: ${confidence} (must be 0–1)`);
  }

  const maxPositionUsd  = parseFloat(process.env.MAX_POSITION_SIZE_USD)  || 500;
  const maxRiskPct      = parseFloat(process.env.MAX_ACCOUNT_RISK_PCT)   || 2;
  const kellyFraction   = parseFloat(process.env.KELLY_FRACTION)         || 0.25;

  // Fetch live balance — hard abort if this fails
  const balance = await getAccountBalance(walletAddress);

However, the resulting order is authorized using an independently configured private key:

js
async function placeOrder({ coin, isBu
...[truncated 4321 chars]
Remediation
View remediation

Remediation Suggestions

  1. At live startup, derive the signer address from HYPERLIQUID_PRIVATE_KEY using ethers.Wallet and reject startup unless it exactly matches HYPERLIQUID_WALLET_ADDRESS.
  2. Use the derived signer address—not a separately trusted environment value—for every balance, position, and exposure query.
  3. Construct a single immutable signer context containing the private key and derived address, then pass that context through sizing and execution functions.
  4. Add a defense-in-depth identity check inside placeOrder() so direct callers cannot bypass the startup validation.
  5. Before signing each order, query the signer account's current positions and balance and enforce MAX_OPEN_POSITIONS, MAX_ACCOUNT_RISK_PCT, and the absolute position cap against that same identity.
  6. Treat failure to derive the signer address, query its account state, or verify identity equality as fail-closed conditions.
  7. Add automated tests covering mismatched addresses, missing addresses, stale configuration, direct invocation of placeOrder(), and signer-account risk-limit enforcement.

A suitable startup pattern is:

js
const { Wallet } = require('ethers');

const privateKey = process.env.HYPERLIQUID_PRIVATE_KEY;
const configuredAddress = process.env.HYPERLIQUID_WALLET_ADDRESS;
const signerAddress = new Wallet(privateKey).address;

if (
  !configuredAddress ||
  signerAddress.toLowerCase() !== configuredAddress.toLowerCase()
) {
  throw new Error(
    'HYPERLIQUID_WALLET_ADDRESS does not match HYPERLIQUID_PRIVATE_KEY'
  );
}

// Use signerAddress for all subsequent account-state queries.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (59)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 17)May include surrounding context.

Step 2 — Configure your environment

bash
cp .env.example .env

Open .env and fill in at minimum:

  • HYPERLIQUID_PRIVATE_KEY — your Hyperliquid account private key

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The Hyperliquid-focused description does not disclose THORNode/NineRealms network use, swap memo construction, or inbound vault metadata retrieval. Concealing cross-chain functionality is particularly dangerous in a wallet-integrated skill because it changes the transaction surface, counterparties, and irreversible fund movement risks users are consenting to.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The Hyperliquid-focused description does not disclose THORNode/NineRealms network use, swap memo construction, or inbound vault metadata retrieval. Concealing cross-chain functionality is particularly dangerous in a wallet-integrated skill because it changes the transaction surface, counterparties, and irreversible fund movement risks users are consenting to.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The Hyperliquid-focused description does not disclose THORNode/NineRealms network use, swap memo construction, or inbound vault metadata retrieval. Concealing cross-chain functionality is particularly dangerous in a wallet-integrated skill because it changes the transaction surface, counterparties, and irreversible fund movement risks users are consenting to.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The Hyperliquid-focused description does not disclose THORNode/NineRealms network use, swap memo construction, or inbound vault metadata retrieval. Concealing cross-chain functionality is particularly dangerous in a wallet-integrated skill because it changes the transaction surface, counterparties, and irreversible fund movement risks users are consenting to.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Requesting a private key in a .env file is a real credential-access pattern, and in this context it is highly sensitive because the key can authorize financial actions. Even if intended for legitimate trading, collecting raw private keys substantially raises the blast radius of any code defect, malicious dependency, or user workstation compromise.

Content

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

bash
npm install
cp .env.example .env
# Fill in your Hyperliquid private key + wallet address + trading limits
node src/setup-check.js   # validate before going live

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node src/setup-check.js # validate before going live

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node src/setup-check.js # validate before going live

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node src/index.js start --paper

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node src/index.js start --paper

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node src/index.js start --paper

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node src/index.js start --paper

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node src/index.js start --paper

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node src/index.js start --paper

Known Vulnerable Dependency: axios==1.13.6 — 16 advisory(ies): CVE-2026-44494 (axios Vulnerable to Full Man-in-the-Middle via Prototype Pollution Gadget in `co); CVE-2026-44495 (axios Vulnerable to Credential Theft and Response Hijacking via Prototype Pollut); CVE-2025-62718 (Axios has a NO_PROXY Hostname Normalization Bypass that Leads to SSRF) +13 more

High
Category
Supply Chain
Confidence
92% confidence
Finding

The lockfile pins axios 1.13.6, and the supplied advisories include high-risk issues such as SSRF/proxy bypass and prototype-pollution-related request manipulation. In an autonomous trading agent that makes outbound network calls and may handle API credentials, a vulnerable HTTP client materially increases risk of request redirection, credential leakage, or attacker-influenced communications.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: form-data==4.0.5 — 1 advisory(ies): CVE-2026-12143 (form-data: CRLF injection in form-data via unescaped multipart field names and f)

High
Category
Supply Chain
Confidence
80% confidence
Finding

form-data 4.0.5 is reported as vulnerable to CRLF injection via unescaped multipart field names/filenames. This is only exploitable if the application builds multipart requests from attacker-controlled values, but if present it can corrupt HTTP message structure and enable request smuggling-style effects against downstream services.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ws==8.17.1 — 2 advisory(ies): CVE-2026-45736 (ws: Uninitialized memory disclosure); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
87% confidence
Finding

ws 8.17.1 is flagged for memory disclosure and memory exhaustion denial-of-service issues. Since a trading agent may rely on real-time websocket market feeds, a vulnerable websocket client increases exposure to malicious or compromised upstream servers causing crashes, degraded execution, or possible unintended data exposure.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: axios==1.13.6 — 16 advisory(ies): CVE-2026-44494 (axios Vulnerable to Full Man-in-the-Middle via Prototype Pollution Gadget in `co); CVE-2026-44495 (axios Vulnerable to Credential Theft and Response Hijacking via Prototype Pollut); CVE-2025-62718 (Axios has a NO_PROXY Hostname Normalization Bypass that Leads to SSRF) +13 more

High
Category
Supply Chain
Confidence
98% confidence
Finding

The manifest permits installation of axios 1.13.6, which the finding identifies as carrying multiple advisories including SSRF and man-in-the-middle/prototype-pollution-related issues. In an autonomous trading agent that consumes external market data and may interact with authenticated endpoints, a vulnerable HTTP client can enable request manipulation, credential theft, response hijacking, or malicious data injection that influences trading decisions.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The file implements THORChain quote, scan, and inbound-address utilities, which materially diverge from the advertised Hyperliquid perpetual-futures trading functionality. In an agent ecosystem, this kind of capability mismatch is dangerous because users or orchestrators may grant permissions, trust, or operational context based on the manifest, while the skill actually performs unrelated cross-chain routing and external network access.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
88% confidence
Finding

The documentation instructs users to place a Hyperliquid private key into a local .env file to enable signed order execution. While common in developer tooling, this is still credential exposure risk because .env files are easily leaked through shell history, backups, screenshots, misconfigured repos, or downstream tooling, and here the secret directly controls trading funds.

Content

Scanner excerpt · skills/vantage/SKILL.md (reported line 42)May include surrounding context.

bash
npm install
cp .env.example .env
# Fill in your Hyperliquid private key + wallet address + trading limits
node src/setup-check.js   # validate before going live

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · src/hyperliquid.js (reported line 55)May include surrounding context.

js
async function getPositions(walletAddress) {
  if (!walletAddress) {
    return [
      { coin: 'DEMO', side: 'long', size: 0, entryPrice: 0, unrealisedPnl: 0, note: 'Set HYPERLIQUID_WALLET_ADDRESS in .env for live positions' },
    ];
  }
  const data = await post({ type: 'clearinghouseState', user: walletAddress });

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · src/index.js (reported line 582)May include surrounding context.

js
async function getPositions(walletAddress) {
  if (!walletAddress) {
    return [
      { coin: 'DEMO', side: 'long', size: 0, entryPrice: 0, unrealisedPnl: 0, note: 'Set HYPERLIQUID_WALLET_ADDRESS in .env for live positions' },
    ];
  }
  const data = await post({ type: 'clearinghouseState', user: walletAddress });

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · src/trader.js (reported line 55)May include surrounding context.

js
* @returns {{ valid: boolean, address?: string, error?: string }}
 */
function validatePrivateKey(key) {
  if (!key) return { valid: false, error: 'HYPERLIQUID_PRIVATE_KEY is not set in .env' };

  if (!/^0x[0-9a-fA-F]{64}$/.test(key)) {
    return {

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README states that OpenAI may be used as a fallback despite marketing the agent as running locally, but it does not clearly warn users that trading signals, positions, or other decision-context data could be transmitted to a third-party cloud service. In a financial trading agent that handles private-key-backed execution, this omission can mislead users about data exposure and privacy boundaries, increasing the risk of unintended off-machine disclosure.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill advertises behavior that clearly requires environment-variable access and outbound networking, but it does not declare any explicit tool scope or permissions. That weakens sandboxing and user review because operators cannot easily see or constrain what resources the skill expects to access before installation or execution.

Content

No source excerpt is available for this finding.