Back to skill

Security audit

Apex

Security checks for vulnerabilities and agentic risk

Overview

This ApeX trading skill is mostly transparent about its purpose, but it handles real trading authority with weak local safeguards and sensitive financial data handling that users should review carefully.

Review this before installing. Use testnet first, provide the least-privileged ApeX API key possible, do not reuse the Omni seed elsewhere, and require explicit confirmation for every trade, close, cancel, or reward submission. Treat generated market signals as informational only, and remove or protect any generated trading-state.json file containing account data.

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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/apex.mjs:192
Finding

Trading Orders Accept Unvalidated Size and Price Parameters

Content
View full analysis

Vulnerability Details

File Location: scripts/apex.mjs:192-246
Vulnerability Type: Insufficient validation of financial transaction parameters
Risk Level: High

Vulnerable Code

js
case 'market-buy':
case 'market-sell': {
  const apexClient = await createPrivateClient();
  const symbol = normalizeSymbol(args[1]);
  const size = args[2];
  if (!symbol || !size) {
    throw new Error(`Usage: apex ${command} <coin> <size>`);
  }

  const side = command === 'market-buy' ? 'BUY' : 'SELL';
  const symbolInfo = apexClient.symbols?.[symbol];
  if (!symbolInfo?.l2PairId) {
    throw new Error(`Unknown symbol: ${symbol}`);
  }

  let price = '';
  try {
    const worst = await apexClient.privateApi.getWorstPrice(symbol, size, side);
    price = worst?.worstPrice || '';
  } catch (err) {
    const ticker = await getTickerPrice(apexClient, symbol);
    price = ticker?.lastPrice || '';
  }

  if (!price) throw new Error(`Unable to determine price for ${symbol}`);

  const makerFeeRate = apexClient.account?.contractAccount?.makerFeeRate || '0';
  const takerFeeRate = apexClient.account?.contractAccount?.takerFeeRate || '0';
  const limitFee = calculateLimitFee(
    price,
    size,
    takerFeeRate,
    symbolInfo.baseCoinRealPrecision,
  );

  const order = {
    pairId: symbolInfo.l2PairId,
    makerFeeRate,
    takerFeeRate,
    symbol,
    side,
    type: 'MARKET',
    size: String(size),
    price: String(price),
    limitFee,
    reduceOnly: false,
    timeInForce: 'IMMEDIATE_OR_CANCEL',
    expiration: Math.floor(Date.now() / 1000 + 30 * 24 * 60 * 60),
  };

  const result = await apexClient.privateApi.createOrder(order);
  console.log(JSON.stringify(result, null, 2));
  break;
}

case 'limit-buy':
case 'limit-sell': {
  const apexClient = await createPrivateClient();
  const symbol = normalizeSymbol(args[1]);
  const si
...[truncated 2115 chars]
Remediation
View remediation

Remediation Suggestions

  • Parse size and price with BigNumber and reject invalid, non-finite, zero, or negative values.
  • Validate size, price, and notional against the exchange metadata for the selected symbol.
  • Enforce decimal precision before constructing the order.
  • Retrieve current account equity, available margin, and existing exposure before submission.
  • Define an explicit maximum notional and reject or require heightened confirmation for trades exceeding it.
  • Compare limit prices with a fresh market price and reject or prominently confirm prices outside a configured deviation.
  • Generate a complete order preview and require explicit confirmation immediately before createOrder().
  • Add automated tests for negative numbers, zero, exponent notation, NaN, Infinity, excessive precision, and extreme notional values.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/apex.mjs:220
Finding

Position-Closing Workflow Can Reverse Exposure Because Orders Are Not Reduce-Only

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:192-195; scripts/apex.mjs:220-231
Vulnerability Type: Unsafe position-closing order construction
Risk Level: High

Vulnerable Code

SKILL.md directs the agent to close a position using an ordinary opposite-side market order:

md
**"Close my ETH position"**
1. Run `positions` to get current ETH position size
2. If long → market-sell, if short → market-buy
3. Execute with position size
4. Report result

The corresponding market-order implementation explicitly disables reduce-only behavior:

js
const order = {
  pairId: symbolInfo.l2PairId,
  makerFeeRate,
  takerFeeRate,
  symbol,
  side,
  type: 'MARKET',
  size: String(size),
  price: String(price),
  limitFee,
  reduceOnly: false,
  timeInForce: 'IMMEDIATE_OR_CANCEL',
  expiration: Math.floor(Date.now() / 1000 + 30 * 24 * 60 * 60),
};

const result = await apexClient.privateApi.createOrder(order);

Technical Analysis

An opposite-side order is not equivalent to a safe close operation unless it is constrained to reduce the current position. The workflow reads a position and then submits a later order with reduceOnly: false. This creates a time-of-check/time-of-use window.

If the position is reduced or closed between observation and execution, the submitted order may exceed the remaining position and open exposure in the opposite direction. Duplicate execution can produce the same result. The risk also applies when an agent retries a command after receiving an ambiguous response.

Attack Path

  1. The agent reads a long or short position and records its size.
  2. Before the closing order is submitted, another order, liquidation event, manual action, or concurrent process changes the position.
  3. The agent invokes market-sell or market-buy using the stale size.
  4. The CLI creates the order with reduceOnly: false.
  5. ApeX fills the order be ...[truncated 485 chars]
Remediation
View remediation

Remediation Suggestions

  • Implement a dedicated close-position command instead of reusing general market buy and sell commands.
  • Refresh the current position immediately before constructing the closing order.
  • Set reduceOnly: true for all position-closing orders.
  • Cap the close size to the absolute value of the current position.
  • Verify that the requested side is opposite to the live position side.
  • Reject the operation if the position is already closed or changed materially.
  • Require final user confirmation that includes the refreshed symbol, side, size, price estimate, and reduce-only status.
  • Use idempotency controls or an operation identifier to prevent duplicate close submissions.
  • Do not automatically retry after an ambiguous exchange response; query order and position state first.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/check-positions.mjs:136
Finding

Portfolio and Account Information Is Persisted in an Unprotected Plaintext File

Content
View full analysis

Vulnerability Details

File Location: scripts/check-positions.mjs:136-149
Vulnerability Type: Plaintext storage of sensitive financial data
Risk Level: Medium

Vulnerable Code

js
try {
  let tradingState = null;
  try {
    tradingState = JSON.parse(readFileSync(stateFile, 'utf8'));
  } catch (err) {
    if (err.code !== 'ENOENT') {
      throw err;
    }
    tradingState = { parameters: {} };
  }
  tradingState.last_check = new Date().toISOString();
  tradingState.current_positions = positions;
  tradingState.parameters.account_size =
    parseFloat(balance.totalEquityValue || '0');
  writeFileSync(stateFile, JSON.stringify(tradingState, null, 2));
  console.log('\nTrading state updated');
} catch (err) {
  console.log('\nCould not update trading state:', err.message);
}

The destination is defined inside the source directory:

js
const stateFile = new URL('./trading-state.json', import.meta.url).pathname;

Technical Analysis

The monitor writes full current position objects and total account size into scripts/trading-state.json. The write operation does not specify restrictive permissions, encryption, or data minimization. Its effective permissions therefore depend on the process umask and surrounding directory permissions.

Placing generated financial state inside the Skill's source tree also increases the chance that it will be copied, archived, backed up, or committed with the project. The provided directory structure does not contain a .gitignore protecting this generated file.

This is not Agent memory poisoning because the data written is not used to introduce attacker-controlled instructions into future sessions. It is a local sensitive-data storage weakness.

Attack Path

  1. A user runs check-positions.mjs with valid ApeX credentials.
  2. The script retrieves the user's positions and account equity.
  3. It serializes those values int ...[truncated 744 chars]
Remediation
View remediation

Remediation Suggestions

  • Do not persist portfolio data unless persistence is explicitly requested and required.
  • Store only the minimum derived values needed for monitoring rather than complete position objects.
  • Move generated state outside the source tree to a user-specific application-data directory.
  • Create the destination directory with mode 0o700 and the file with mode 0o600.
  • Use an atomic write pattern with a securely permissioned temporary file followed by rename.
  • Encrypt the state at rest if it must survive sessions.
  • Add trading-state.json and other generated state files to .gitignore.
  • Document retention, deletion, and sensitivity requirements.
  • Validate the existing file type and ownership before overwriting it to reduce symlink and unintended-file risks.

T08 · Insecure Dependencies

Warning
Location
scripts/package.json:5
Finding

Wallet Seed and API Credentials Are Entrusted to a Pre-Release SDK with a Mixed-Registry Dependency Lockfile

Content
View full analysis

Vulnerability Details

File Location: scripts/package.json:5-9; scripts/package-lock.json:576-597,710-714; scripts/apex.mjs:54-64
Vulnerability Type: Elevated dependency and supply-chain trust exposure
Risk Level: Medium

Vulnerable Code and Configuration

The project uses a pre-release trading SDK:

json
{
  "name": "apex-cli",
  "version": "1.0.0",
  "type": "module",
  "dependencies": {
    "apexomni-connector-node": "0.3.2-alpha.1",
    "bignumber.js": "^9.1.2",
    "node-fetch": "^3.3.2"
  }
}

The SDK receives all private authentication material, including the wallet seed:

js
async function createPrivateClient() {
  const apexClient = new ApexClient.omni(getEnv());
  const credentials = getCredentials();
  await apexClient.init(
    {
      key: credentials.key,
      passphrase: credentials.passphrase,
      secret: credentials.secret,
    },
    credentials.seed,
  );
  return apexClient;
}

The lockfile pins the alpha SDK from npm:

json
"apexomni-connector-node": {
  "version": "0.3.2-alpha.1",
  "resolved": "https://registry.npmjs.org/apexomni-connector-node/-/apexomni-connector-node-0.3.2-alpha.1.tgz",
  "integrity": "sha512-8sd7UsWcCODinYD81FsRHthdCBHEtyRPYlv/kKdBZK1VwO3//XFUJijDInqw5hwg7K7/SjAcR4pjAM0SCwLiJQ==",
  "requires": {
    "axios": "^1.6.7",
    "big.js": "^6.2.1",
    "bigint-buffer": "^1.1.5",
    "bignumber.js": "^9.0.1",
    "crypto": "^1.0.1",
    "crypto-browserify": "^3.12.0",
    "crypto-js": "^4.2.0",
    "es6-promisify": "^7.0.0",
    "ethereum-cryptography": "0.1.3",
    "ethers": "5.5.4",
    "isomorphic-ws": "^4.0.1",
    "lodash": "^4.17.21",
    "qs": "^6.11.1",
    "viem": "^2.21.22",
    "web3": "1.7.4"
  }
}

A direct dependency is retrieved from a different registry:

json
"bignumber.js": {
  "version": "9.3.1",
  "resolved": "https://registry.npmmi
...[truncated 2350 chars]
Remediation
View remediation

Remediation Suggestions

  • Replace the alpha SDK with a reviewed, stable, officially supported release where available.
  • Verify the package publisher, source repository, release provenance, and package signatures before adoption.
  • Standardize all locked artifacts on an explicitly approved registry.
  • Regenerate the version 1 lockfile with a supported modern npm release and review all resulting source URLs.
  • Use npm ci rather than npm install for reproducible deployment.
  • Run dependency vulnerability and license scans in CI and fail builds on unapproved registries.
  • Review the SDK and critical cryptographic or networking dependencies before upgrades.
  • Use an ApeX API key with only the minimum required trading permissions and no withdrawal permission.
  • Keep the signing seed isolated from unrelated processes and avoid reusing it for other wallets or services.
  • Consider moving signing into a constrained helper or hardware-backed mechanism so the complete seed is not exposed to the general dependency graph.
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (45)

Known Vulnerable Dependency: elliptic==6.5.4 — 7 advisory(ies): CVE-2024-48949 (Elliptic's verify function omits uniqueness validation); CVE-2024-42461 (Elliptic allows BER-encoded signatures); CVE-2025-14505 (Elliptic Uses a Cryptographic Primitive with a Risky Implementation) +4 more

Critical
Category
Supply Chain
Confidence
90% confidence
Finding

elliptic 6.6.1 still carries a reported low-severity cryptographic implementation concern. In a crypto-facing skill, even lower-severity crypto library advisories deserve attention because they affect sensitive operations, though this specific finding appears less severe than the 6.5.4 instance.

Content

No source excerpt is available for this finding.

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

Or use .env file (recommended for security):

bash
cd apex
cp .env.example .env
# Edit .env with your credentials
nano .env

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

bash
cd apex
cp .env.example .env
# Edit .env with your credentials
nano .env

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

bash
cd apex
cp .env.example .env
# Edit .env with your credentials
nano .env

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/apex.mjs price BTC

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/apex.mjs price BTC

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/apex.mjs price BTC

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 scripts/apex.mjs price BTC

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/apex.mjs price BTC

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/apex.mjs price BTC

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/apex.mjs price BTC

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/apex.mjs price BTC

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/apex.mjs price BTC

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/apex.mjs price BTC

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/apex.mjs price BTC

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/apex.mjs price BTC

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/apex.mjs price BTC

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/apex.mjs price BTC

Vague Triggers

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The Chinese trigger examples are extremely generic phrases like '报名活动' and '参加活动', which could match many unrelated conversations and route them into a skill that can submit enrollments or perform other private ApeX actions. In this context, overbroad multilingual triggers are especially risky because the skill has authenticated exchange capabilities and includes a default reward submission behavior.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

This script materially deviates from the declared ApeX skill scope by performing off-platform CoinGecko market analysis and producing trading-oriented output. In a trading skill, capability drift is dangerous because users or downstream agents may treat this script as trusted ApeX functionality and act on recommendations that were never part of the stated account/trading operations.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ws==3.3.3 — 2 advisory(ies): CVE-2024-37890 (ws affected by a DoS when handling a request with many HTTP headers); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
89% confidence
Finding

ws 3.3.3 has known denial-of-service issues involving headers and fragment handling. Because trading integrations often use WebSockets for prices, positions, and order state, a DoS against socket handling can meaningfully disrupt monitoring and trading workflows.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: axios==1.13.5 — 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
86% confidence
Finding

axios is used for outbound network access, and reported issues include SSRF/proxy-bypass and request handling weaknesses that are especially relevant in an agent skill integrating external trading endpoints. In a trading environment, compromised HTTP behavior can expose credentials, misroute requests, or tamper with market/order operations.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: bigint-buffer==1.1.5 — 1 advisory(ies): CVE-2025-3194 (bigint-buffer Vulnerable to Buffer Overflow via toBigIntLE() Function)

High
Category
Supply Chain
Confidence
83% confidence
Finding

bigint-buffer is flagged for a buffer overflow in a numeric conversion path. In a crypto/trading stack that routinely parses binary and large integer data, memory corruption or process crashes can materially affect reliability and possibly security depending on runtime exposure.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: lodash==4.17.23 — 2 advisory(ies): CVE-2025-13465 (lodash vulnerable to Prototype Pollution via array path bypass in `_.unset` and ); CVE-2021-23337 (lodash vulnerable to Code Injection via `_.template` imports key names)

High
Category
Supply Chain
Confidence
85% confidence
Finding

lodash 4.17.23 carries prototype pollution and code-injection-related advisories. In an agent skill that processes complex inputs and request objects, prototype pollution can cascade into config tampering, SSRF gadgets, auth bypasses, or unexpected behavior in trading operations.

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 has a CRLF injection issue in multipart field handling. If any user-controlled names or filenames are passed into multipart requests, this can alter request structure and potentially smuggle headers or manipulate downstream services.

Content

No source excerpt is available for this finding.