Back to skill

Security audit

00001 Grid Trading Bot

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent demo-only grid trading bot, but it needs Review because it handles exchange credentials and exposes unauthenticated local controls that can start or stop sandbox trading.

Install only if you are comfortable running a local sandbox trading bot that handles exchange API credentials in memory. Use demo/testnet keys only, keep it bound to 127.0.0.1, stop it when finished, avoid visiting untrusted sites while it is running, and update or review dependencies before use.

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

Warning
Location
bot/server.js:139
Finding

Unauthenticated Localhost State-Changing API Enables Cross-Origin Strategy Control

Content
View full analysis

Vulnerability Details

File Location: bot/server.js:139-151, 164-231
Vulnerability Type: Missing authentication and CSRF protection on state-changing localhost endpoints
Risk Level: Medium

Vulnerable Code

js
const app = express();
app.disable('x-powered-by');
app.use((request, response, next) => {
  response.setHeader('X-Content-Type-Options', 'nosniff');
  response.setHeader('X-Frame-Options', 'DENY');
  response.setHeader('Referrer-Policy', 'no-referrer');
  response.setHeader(
    'Content-Security-Policy',
    "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; connect-src 'self'; frame-ancestors 'none'"
  );
  next();
});
app.use(express.json({ limit: '64kb', type: 'application/json' }));

app.post('/api/config', (request, response) => {
  try {
    memoryConfig = validatePayload(request.body);
    writePublicConfig(memoryConfig);
    response.json({ ok: true, credentialsStored: false, paper: true });
  } catch (error) {
    response.status(400).json({ error: error.message });
  }
});

app.post('/api/strategy/start', async (_request, response) => {
  if (running) {
    response.status(409).json({ error: 'Strategy is already running.' });
    return;
  }
  try {
    const exchange = createExchange(memoryConfig);
    running = true;
    abortState = { aborted: false };
    lastActivity = { action: 'starting', at: new Date().toISOString() };
    response.status(202).json({ ok: true, paper: true });

    strategy
      .run(exchange, memoryConfig, abortState, (action) => {
        lastActivity = { action, at: new Date().toISOString() };
      })
      .catch((error) => {
        console.error('[Grid] Strategy failed:', error.message);
        lastActivity = { action: 'error', at: new Date().toISOString() };
      })
      .finally(() => {
        running = false;
        abortStat
...[truncated 3146 chars]
Remediation
View remediation

Remediation Suggestions

  1. Generate a cryptographically random, per-process authentication token when the server starts.
  2. Deliver the token only to the trusted local UI and require it in a custom request header on every state-changing endpoint.
  3. Implement CSRF protection for /api/config, /api/strategy/start, and /api/strategy/stop.
  4. Validate Origin and, where appropriate, Sec-Fetch-Site, rejecting requests not originating from the exact local UI origin.
  5. Validate the Host header against an explicit allowlist such as 127.0.0.1:<configured-port> and reject unexpected hostnames to reduce DNS-rebinding exposure.
  6. Require Content-Type: application/json for every state-changing endpoint, including start and stop, and reject form-compatible requests.
  7. Require an explicit, short-lived confirmation nonce immediately before starting the strategy.
  8. Add automated security tests proving that missing tokens, foreign origins, invalid hosts, and form submissions are rejected.
  9. Retain the existing localhost binding and server-side sandbox enforcement as defense-in-depth controls.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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 (18)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill claims to support demo/sandbox-only configuration and operation, but the detected behavior indicates the bundled bot can place exchange orders, query balances, cancel orders, and run active trading logic without reliable enforcement of sandbox mode. This mismatch is dangerous because users and downstream agents may trust the safety claims and invoke actions that affect real exchange accounts or funds.

Content

No source excerpt is available for this finding.

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · bot/public/index.html (reported line 500)May include surrounding context.

html
</head>
<body>

<!-- ════════════════════════════════════════════════
     Full-bleed candlestick + DOM chart background
     ════════════════════════════════════════════════ -->
<div class="chart-bg"></div>

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The UI explicitly asks for exchange API credentials and the JavaScript sends them to /api/config for persistence, which directly contradicts the stated safety boundary of not accepting credentials and only supporting safe demo/sandbox usage. In a trading-bot context, collecting and storing API keys creates a clear secret-handling risk and broadens the blast radius if the backend, browser session, logs, or storage are exposed.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The UI copy tells users to paste exchange keys, normalizing credential submission through the interface despite the skill metadata saying credentials should never be accepted in chat. In context, this is dangerous because it socially engineers users into disclosing high-value secrets to the application and undermines the advertised trust boundary.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This code actively places and cancels real exchange orders via createLimitBuyOrder, createLimitSellOrder, and cancelOrder, which directly contradicts the skill metadata claiming demo/sandbox-only behavior and configuration preview. In an agent setting, that mismatch can cause unintended live trading if connected to a real account, leading to financial loss, market exposure, and unauthorized trading actions.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill advertises operational steps that involve installing and running a local bot with network and environment interactions, but it does not declare any explicit tool scope or allowed-tools restrictions. That creates an authorization gap where an agent may use broader capabilities than the skill metadata makes visible, increasing the chance of unintended network access, process execution, or environment exposure during bot setup and operation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The form collects API key, secret, and passphrase, and saveConfig() posts them to /api/config without any visible notice explaining backend transmission, persistence, retention, or security properties. Users are therefore induced to submit sensitive secrets without informed consent, increasing the chance of unsafe handling and accidental exposure.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The interface includes direct start and stop controls, enabling operation of the trading bot rather than limiting the skill to installation help, previewing parameters, troubleshooting, or generating configuration. This increases risk because it turns an informational/configuration surface into an execution surface capable of triggering automated trading behavior, even if intended for sandbox mode.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

loadConfig() retrieves stored configuration from the backend and repopulates apiKey, apiSecret, and passphrase fields, demonstrating that secrets are stored server-side and later returned to the client without disclosure. Returning saved secrets to the browser unnecessarily increases exposure through the DOM, autofill-like reuse, shoulder surfing, browser tooling, and client-side compromise.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest frames the skill as safely installing/running the bot in demo or sandbox mode and explicitly says to never accept credentials in chat. In code, the server accepts apiKey/apiSecret/passphrase in requests, stores them in memory, and uses them to instantiate a CCXT exchange client for trading operations, which is a broader behavior than mere parameter preview/config generation.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The module comments describe parameter parsing and grid setup but do not clearly disclose that the strategy will fetch balances, poll tickers, and submit/cancel exchange orders. This misleading documentation increases the chance that operators or orchestration layers will invoke the skill under the false assumption that it is a safe configurator, which amplifies the risk of unintended real-market actions.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: qs==6.15.3 — 2 advisory(ies): CVE-2026-82417 (qs: Denial of Service via Attacker Controlled isBuffer); CVE-2026-82562 (qs array-limit bypass via bracket-key comma parsing)

Low
Category
Supply Chain
Confidence
84% confidence
Finding

The lockfile pins qs to 6.15.3, and the provided advisory data indicates this version is affected by denial-of-service and parsing-bypass issues. In this dependency tree, qs is pulled in through Express/body-parser, so if the bot exposes HTTP endpoints that parse attacker-controlled query strings or request bodies, a remote client could trigger excessive parsing work or bypass expected array-limit assumptions.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: undici==6.27.0 — 3 advisory(ies): CVE-2026-16728 (undici vulnerable to downstream response desynchronization via retry interceptor); CVE-2026-15157 (undici vulnerable to CRLF Injection via blob-like body 'type' property); CVE-2026-16729 (undici vulnerable to cookie attribute injection via unsanitized domain and unpar)

Low
Category
Supply Chain
Confidence
87% confidence
Finding

The lockfile pins undici to 6.27.0, and the advisory information supplied states this version is affected by multiple request/response handling and header/cookie injection flaws. If the bot uses undici with attacker-influenced URLs, headers, blob metadata, retry behavior, or cookie/domain values, these flaws could enable malformed outbound requests, response desynchronization, or header injection against downstream services.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

The dependency uses a caret range (^4.2.0), which permits automatic installation of newer minor and patch releases. This weakens build reproducibility and can unintentionally pull in a compromised or breaking upstream release, increasing supply-chain risk even though package.json alone does not prove active exploitation.

Content

Scanner excerpt · bot/package.json (reported line 11)May include surrounding context.

json
"test": "node tests/security.test.js"
  },
  "dependencies": {
    "ccxt": "^4.2.0",
    "dotenv": "^16.3.1",
    "express": "^4.18.2",
    "undici": "^6.23.0"

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

The dotenv dependency is specified with a caret range, so installs are not fully deterministic and may resolve to different versions over time. In a security-sensitive bot context, this increases supply-chain exposure and makes it easier for an upstream compromise or unexpected package change to enter the environment.

Content

Scanner excerpt · bot/package.json (reported line 12)May include surrounding context.

json
},
  "dependencies": {
    "ccxt": "^4.2.0",
    "dotenv": "^16.3.1",
    "express": "^4.18.2",
    "undici": "^6.23.0"
  }

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

Express is declared with a caret range, allowing future minor/patch updates to be installed implicitly. That creates avoidable supply-chain and reproducibility risk, especially for a service component that may parse and handle network requests.

Content

Scanner excerpt · bot/package.json (reported line 13)May include surrounding context.

json
"dependencies": {
    "ccxt": "^4.2.0",
    "dotenv": "^16.3.1",
    "express": "^4.18.2",
    "undici": "^6.23.0"
  }
}

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The undici dependency is unpinned, which permits installs to drift to newer versions automatically. That is especially risky here because the static findings also indicate a vulnerable resolved undici version, showing how lax version constraints can contribute to exposure.

Content

Scanner excerpt · bot/package.json (reported line 14)May include surrounding context.

json
"ccxt": "^4.2.0",
    "dotenv": "^16.3.1",
    "express": "^4.18.2",
    "undici": "^6.23.0"
  }
}

Known Vulnerable Dependency: undici==6.27.0 — 3 advisory(ies): CVE-2026-16728 (undici vulnerable to downstream response desynchronization via retry interceptor); CVE-2026-15157 (undici vulnerable to CRLF Injection via blob-like body 'type' property); CVE-2026-16729 (undici vulnerable to cookie attribute injection via unsanitized domain and unpar)

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The resolved undici version is reported as 6.27.0 with multiple advisories, including response desynchronization and injection issues. If this bot's server or HTTP client paths process attacker-influenced requests, these flaws could enable request/response smuggling-style behavior or header/cookie manipulation, making the issue more serious than a generic dependency hygiene finding.

Content

No source excerpt is available for this finding.