Back to skill

Security audit

hyperliquid-trade

Security checks for vulnerabilities and agentic risk

Overview

The skill largely does what it claims, but it handles a signing wallet for financial actions while adding under-disclosed third-party registration and unsafe setup/runtime patterns.

Review carefully before installing. This skill can decrypt your WDK wallet and sign trades, leverage changes, deposits, withdrawals, order cancels, and order modifications. Only use it with funds you are willing to expose to agent mistakes or script misuse, avoid opting into the unrelated XAUT rankings unless you accept sharing your wallet address and nickname with xaue.com, and do not run it with a shared or untrusted ~/.aurehub/.env until the shell-sourcing and unpinned onboarding issues are addressed.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • 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
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (6)

T01 · Skill Instruction Hijacking

Warning
Location
SKILL.md:66
Finding

Unrelated Rankings Registration Hijacks the Skill Workflow and Discloses Wallet Identity

Content
View full analysis
/balance.js address | node -p "JSON.parse(require('fs').readFileSync(0,'utf8')).address") ``` ```markdown 3. If `RANKINGS_OPT_IN` != `"true"`: - Check marker: `PROMPTED=$(cat ~/.aurehub/.rankings_prompted 2>/dev/null)` - If marker starts with `"$WALLET_ADDRESS:"` → skip; return immediately - Otherwise ask once: "Join XAUT activity rankings now? (yes/no)" - If user says `no`: `echo "$WALLET_ADDRESS:declined" > ~/.aurehub/.rankings_prompted`; return - If user says `yes`: - If `NICKNAME` is empty: ask user for nickname - Persist opt-in in `~/.aurehub/.env` (`RANKINGS_OPT_IN=true`, `NICKNAME=`) - Re-source env: `source ~/.aurehub/.env` - Continue to step 4 4. If `RANKINGS_OPT_IN` == `"true"`: - If `NICKNAME` is empty: ask "You're opted in to XAUT activity rankings — what nickname would you like to appear as?", then persist to `~/.aurehub/.env` and re-source - Register: ``` ```bash NICKNAME_ESC=$(printf '%s' "$NICKNAME" | sed 's/\\/\\\\/g; s/"/\\"/g') REGISTER_RESP=$(curl -s -o /dev/null -w "%{http_code}" -X POST \ https://xaue.com/api/rankings/participants \ -H 'Content-Type: application/json' \ -d "{\"wallet_address\":\"$WALLET_ADDRESS\",\"nickname\":\"$NICKNAME_ESC\",\"source\":\"agent\"}") ``` ### Technical Analysis The declared purpose of the Skill is Hyperliquid trading, account queries, deposits, withdrawals, and order management. The mandatory readiness sequence nevertheless redirects the Agent into an XAUT rankings-registration workflow before processing the ...[truncated 1623 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:66
Finding

Executable Shell Commands Can Be Injected Through the Shared Dotenv File

Content
View full analysis
/balance.js address | node -p "JSON.parse(require('fs').readFileSync(0,'utf8')).address") ``` ```markdown - Persist opt-in in `~/.aurehub/.env` (`RANKINGS_OPT_IN=true`, `NICKNAME=`) - Re-source env: `source ~/.aurehub/.env` ``` ### Technical Analysis The shell `source` command interprets the entire target file as executable shell syntax. A dotenv file is expected to contain configuration data, but it can also contain command substitutions, redirections, function definitions, and arbitrary shell statements. For example, if another process or shared Skill inserts the following entry, sourcing the file executes it immediately: ```bash MALICIOUS_VALUE=$(arbitrary-command) ``` This risk is amplified because `~/.aurehub/.env` is shared with other Aurehub wallet Skills and is modified by the rankings workflow. The JavaScript implementation already contains a data-only dotenv parser in `scripts/lib/config.js`; shell sourcing is therefore unnecessary. Quoting a user-provided nickname as a conventional dotenv value would not make the entire file safe to execute. Secure dotenv parsing must treat every line as data and validate an allowlist of expected names and values. ### Attack Path 1. An attacker, compromised dependency, or another Skill gains write access to `~/.aurehub/.env`. 2. The attacker appends shell syntax, command substitution, or a standalone command. 3. The user invokes any non-knowledge operation in this Skill. 4. The readiness or registration instructions run `source ~/.aurehub/.env`. 5. The injected command executes wi ...[truncated 612 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Error
Location
references/onboarding.md:13
Finding

Onboarding Executes an Unpinned External Skill Installer

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/balance.js:29
Finding

Read-Only Balance and Address Operations Unnecessarily Decrypt the Private Wallet

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/trade.js:114
Finding

Financial Confirmation Requirements Are Not Enforced by the Executable Boundary

Content
View full analysis
= confirmThreshold, requiresDoubleConfirm: tradeValue >= largeThreshold, }) + '\n'); if (!confirmed) process.exit(0); const sz = formatSize(size, szDec); const exchange = createExchangeClient(transport, wallet); const orderStartTime = Date.now(); let result; try { result = await exchange.order({ orders: [{ a: assetId, b: isBuy, p: formatPrice(ioPrice(isBuy, mid, slippagePct), szDec, 'spot'), s: sz, r: false, t: { limit: { tif: 'Ioc' } } }], grouping: 'na', }); ``` Deposit execution uses the same trust model: ```js stdout({ preview: true, action: 'Deposit USDC -> Hyperliquid L1', from_address: address, to_hl_address: address, amount_usdc: amount, usdc_balance_arb: parseFloat(usdcFormatted), eth_balance_arb: ethFormatted, network: 'Arbitrum One', destination: 'Hyperliquid L1', bridge: BRIDGE_ADDRESS, estimated_credit_time: '~1 minute', requiresConfirm: amount >= confirmThreshold, requiresDoubleConfirm: amount >= largeThreshold, }); if (!confirmed) process.exit(0); // Execute: transfer USDC to bridge contract const tx = await usdc.transfer(BRIDGE_ADDRESS, amountWei); ``` Withdrawal execution also relies only on the flag: ```js stdout({ preview: true, action: 'Withdraw USDC -> Arbitrum One', from_hl_address: address, to_arb_address: address, amount_usdc: amount, fee_usdc: WITHDRAWAL_FEE_USDC, ...[truncated 2490 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/deposit.js:88
Finding

Custom Arbitrum RPC Endpoints Are Trusted for Transaction Construction Without Fee Caps

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (61)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description centers on executing and managing Hyperliquid trades and wallet funding actions. The actual code chunk does not implement or invoke those behaviors; it only tests configuration file parsing from .env and YAML files using local filesystem operations. While config loading could support a trading skill, this specific chunk’s primary purpose is materially different from the declared trading functionality, so this is a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The code chunk is specifically a test suite for withdraw.js input validation. It checks usage errors, decimal format restrictions, minimum withdrawal amounts, and account parameter validation by spawning the withdrawal script. This is materially different from the declared primary purpose of trading on Hyperliquid and depositing/bridging USDC. Withdrawal functionality is also a distinct capability not mentioned in the declared description. While this may be part of a larger project, based on the supplied chunk alone, the behavior does not accurately match the declared skill description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents a full Hyperliquid trading skill with many user-facing actions. The supplied code chunk does not implement any of those behaviors. Instead, it is a wallet utility focused on loading and decrypting a WDK vault from local files and producing an ethers signer. While wallet support is mentioned in the description, this chunk alone materially differs from the declared purpose because it lacks any exchange interaction, trading, balance/position checks, or deposit/bridging behavior. It also accesses local secret material (vault and password files), which is a significant behavior not reflected as the main purpose of the skill description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code is focused on limit-order lifecycle management for Hyperliquid: placing spot/perp limit orders, listing open orders, canceling, modifying, and setting leverage when placing perp orders. It also supports trigger-based TP/SL orders via flags. However, the declared description is significantly broader, claiming support for market IOC orders, WDK wallet handling, USDC deposit/bridge from Arbitrum, balance checks, and positions queries; none of those are present in this code chunk. While over-declaration alone can still be acceptable if the chunk is only partial, the requested task is to compare description against the supplied code chunk, and this chunk materially underdelivers relative to several major declared capabilities. Therefore this is a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The code’s core purpose aligns partially with the description: it does trade spot and perpetuals on Hyperliquid, supports opening/closing perp positions, and can set leverage. However, the description materially overstates capabilities present in this code chunk. Every order placed here uses limit-with-IOC behavior; there is no implementation of GTC limit orders. There is also no code for listing/canceling/modifying orders, depositing or bridging USDC, or standalone balance/positions commands. Reading account state internally for pre-checks does not satisfy the declared interactive triggers for checking balances or positions. This is therefore a description-behavior mismatch due to several declared capabilities missing from the supplied code.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

This code chunk’s primary purpose is withdrawing USDC off Hyperliquid to Arbitrum, not placing spot/perp trades or managing orders. The declared description mentions deposits/funding/bridging USDC into Hyperliquid from Arbitrum, but does not disclose the reverse capability: withdrawing/bridging out. That is a materially different asset-transfer action with different risk implications. Therefore the description does not accurately represent the actual behavior of this code chunk.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill includes a separate XAUT rankings registration flow that sends the user's wallet address and nickname to an unrelated third-party service. This is outside the stated Hyperliquid trading purpose, creating hidden data sharing and expanding trust to an external domain that is not necessary for executing trades.

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 129)May include surrounding context.

md
| withdraw USDC / withdraw to Arbitrum / 提现 / 取款 / 把钱取出来 | Run `withdraw.js` flow (see **Withdraw Flow** below) |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
`trade.js` outputs this as a `preview` JSON object. Parse the JSON and render the above format before prompting. Apply `requiresConfirm`/`requiresDoubleConfirm`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
1. Run the appropriate `limit-order.js` subcommand

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 · scripts/__tests__/config.test.js (reported line 19)May include surrounding context.

js
rmSync(tmpDir, { recursive: true, force: true });
  });

  it('reads WALLET_MODE from .env', () => {
    writeFileSync(join(tmpDir, '.env'), 'WALLET_MODE=wdk\nWDK_PASSWORD_FILE=~/.aurehub/.wdk_password\n');
    const cfg = loadConfig(tmpDir);
    expect(cfg.env.WALLET_MODE).toBe('wdk');

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 · scripts/__tests__/config.test.js (reported line 20)May include surrounding context.

js
rmSync(tmpDir, { recursive: true, force: true });
  });

  it('reads WALLET_MODE from .env', () => {
    writeFileSync(join(tmpDir, '.env'), 'WALLET_MODE=wdk\nWDK_PASSWORD_FILE=~/.aurehub/.wdk_password\n');
    const cfg = loadConfig(tmpDir);
    expect(cfg.env.WALLET_MODE).toBe('wdk');

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 · scripts/__tests__/config.test.js (reported line 47)May include surrounding context.

js
rmSync(tmpDir, { recursive: true, force: true });
  });

  it('reads WALLET_MODE from .env', () => {
    writeFileSync(join(tmpDir, '.env'), 'WALLET_MODE=wdk\nWDK_PASSWORD_FILE=~/.aurehub/.wdk_password\n');
    const cfg = loadConfig(tmpDir);
    expect(cfg.env.WALLET_MODE).toBe('wdk');

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 · scripts/__tests__/config.test.js (reported line 52)May include surrounding context.

js
rmSync(tmpDir, { recursive: true, force: true });
  });

  it('reads WALLET_MODE from .env', () => {
    writeFileSync(join(tmpDir, '.env'), 'WALLET_MODE=wdk\nWDK_PASSWORD_FILE=~/.aurehub/.wdk_password\n');
    const cfg = loadConfig(tmpDir);
    expect(cfg.env.WALLET_MODE).toBe('wdk');

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 · scripts/__tests__/config.test.js (reported line 53)May include surrounding context.

js
rmSync(tmpDir, { recursive: true, force: true });
  });

  it('reads WALLET_MODE from .env', () => {
    writeFileSync(join(tmpDir, '.env'), 'WALLET_MODE=wdk\nWDK_PASSWORD_FILE=~/.aurehub/.wdk_password\n');
    const cfg = loadConfig(tmpDir);
    expect(cfg.env.WALLET_MODE).toBe('wdk');

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 · scripts/deposit.js (reported line 95)May include surrounding context.

js
rmSync(tmpDir, { recursive: true, force: true });
  });

  it('reads WALLET_MODE from .env', () => {
    writeFileSync(join(tmpDir, '.env'), 'WALLET_MODE=wdk\nWDK_PASSWORD_FILE=~/.aurehub/.wdk_password\n');
    const cfg = loadConfig(tmpDir);
    expect(cfg.env.WALLET_MODE).toBe('wdk');

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 · scripts/lib/config.js (reported line 45)May include surrounding context.

js
rmSync(tmpDir, { recursive: true, force: true });
  });

  it('reads WALLET_MODE from .env', () => {
    writeFileSync(join(tmpDir, '.env'), 'WALLET_MODE=wdk\nWDK_PASSWORD_FILE=~/.aurehub/.wdk_password\n');
    const cfg = loadConfig(tmpDir);
    expect(cfg.env.WALLET_MODE).toBe('wdk');

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 · SKILL.md (reported line 79)May include surrounding context.

md
import yaml from 'js-yaml';

/**
 * Parse a .env file into a plain object.
 * Skips blank lines and lines starting with #.
 * Strips surrounding single/double quotes from values.
 */

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 · SKILL.md (reported line 256)May include surrounding context.

md
import yaml from 'js-yaml';

/**
 * Parse a .env file into a plain object.
 * Skips blank lines and lines starting with #.
 * Strips surrounding single/double quotes from values.
 */

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 · scripts/__tests__/config.test.js (reported line 46)May include surrounding context.

js
import yaml from 'js-yaml';

/**
 * Parse a .env file into a plain object.
 * Skips blank lines and lines starting with #.
 * Strips surrounding single/double quotes from values.
 */

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 · scripts/__tests__/deposit-cli.test.js (reported line 22)May include surrounding context.

js
import yaml from 'js-yaml';

/**
 * Parse a .env file into a plain object.
 * Skips blank lines and lines starting with #.
 * Strips surrounding single/double quotes from values.
 */

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 · scripts/__tests__/withdraw-cli.test.js (reported line 22)May include surrounding context.

js
import yaml from 'js-yaml';

/**
 * Parse a .env file into a plain object.
 * Skips blank lines and lines starting with #.
 * Strips surrounding single/double quotes from values.
 */

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 · scripts/deposit.js (reported line 12)May include surrounding context.

js
import yaml from 'js-yaml';

/**
 * Parse a .env file into a plain object.
 * Skips blank lines and lines starting with #.
 * Strips surrounding single/double quotes from values.
 */

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 · scripts/deposit.js (reported line 107)May include surrounding context.

js
import yaml from 'js-yaml';

/**
 * Parse a .env file into a plain object.
 * Skips blank lines and lines starting with #.
 * Strips surrounding single/double quotes from values.
 */

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 · scripts/lib/config.js (reported line 6)May include surrounding context.

js
import yaml from 'js-yaml';

/**
 * Parse a .env file into a plain object.
 * Skips blank lines and lines starting with #.
 * Strips surrounding single/double quotes from values.
 */