Back to skill

Security audit

Molt Trader Skill

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a legitimate simulated-trading SDK, but it needs review because it can change trading-account state and may send an API key to any configured endpoint.

Install only if you understand that agents using this skill can open, close, and manage simulated trading positions. Use a scoped Molt Trader API key, keep MOLT_TRADER_BASE_URL pointed only at a trusted HTTPS Molt endpoint or an intentional local dev server, avoid automatic retries for state-changing calls unless the API supports idempotency, and update the dependency chain before using it in CI or shared environments.

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

T09 · Insecure Skill Coding Practices

Error
Location
src/client.ts:189
Finding

Bearer API Key Can Be Forwarded to an Arbitrary or Insecure Endpoint

Content
View full analysis
controller.abort(), this.timeout); try { const response = await fetch(url, { ...options, signal: controller.signal, }); ``` The examples allow the destination to come directly from an environment variable: ```typescript const client = new MoltTraderClient({ apiKey: process.env.MOLT_TRADER_API_KEY || '', baseUrl: process.env.MOLT_TRADER_BASE_URL || 'http://localhost:3000', }); ``` ### Technical Analysis The bearer token is legitimately required for the declared authenticated simulator API. Therefore, its transmission is not covert exfiltration by itself. The vulnerability is that `baseUrl` is accepted without validating its protocol or destination before the client attaches the API key to every request. Any caller or environment variable can select an arbitrary HTTP or HTTPS host. An attacker-controlled HTTPS host would receive the bearer token directly. A non-loopback plaintext HTTP endpoint would additionally expose the token to network interception or modification. The default production endpoint uses HTTPS, and the examples default to a loopback development end ...[truncated 1499 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/client.ts:180
Finding

Automatic Retries Can Duplicate State-Changing Trading Operations

Content
View full analysis
{ this.log('debug', `Opening ${config.type} position: ${config.symbol} x${config.shares}`); try { const response = await this.request('POST', '/api/simulator/positions', { symbol: config.symbol, type: config.type, shares: config.shares, orderType: config.orderType || 'market', limitPrice: config.limitPrice, }); this.log('info', `Position opened: ${response.id}`); return response; ``` ```typescript async requestLocate(config: LocateRequest): Promise { this.log('debug', `Requesting locate: ${config.symbol} x${config.shares}`); try { return await this.request('POST', '/api/simulator/locate', config); ``` The shared request function retries all methods, including `POST`: ```typescript private async request( method: 'GET' | 'POST' | 'PUT' | 'DELETE', endpoint: string, data?: unknown ): Promise { let lastError: Error | null = null; for (let attempt = 0; attempt < this.retryAttempts; attempt++) { try { const url = `${this.baseUrl}${endpoint}`; const options: RequestInit = { method, headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${this.apiKey}`, }, body: data ? JSON.stringify(data) : undefined, }; const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), this.timeout); try { const response = await fetch(url, { ...options, signal: controller.signal, }); clearTimeout(timeout); if (!response.ok) { const error = await response.json().catch(() ...[truncated 3141 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (15)

Known Vulnerable Dependency: brace-expansion==1.1.12 — 4 advisory(ies): CVE-2026-13149 (brace-expansion: DoS via exponential-time expansion of consecutive non-expanding); CVE-2026-33750 (brace-expansion: Zero-step sequence causes process hang and memory exhaustion); CVE-2026-14257 (brace-expansion: DoS via unbounded expansion length causing an out-of-memory pro) +1 more

High
Category
Supply Chain
Confidence
89% confidence
Finding

brace-expansion 1.1.12 has multiple reported denial-of-service issues caused by pathological brace patterns that trigger excessive expansion, hangs, or memory exhaustion. Here it is a transitive dependency used by glob/minimatch in development tooling, which reduces likelihood, but any processing of attacker-influenced glob patterns could still cause local resource exhaustion.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: flatted==3.3.3 — 2 advisory(ies): CVE-2026-32141 (flatted vulnerable to unbounded recursion DoS in parse() revive phase); CVE-2026-33228 (Prototype Pollution via parse() in NodeJS flatted)

High
Category
Supply Chain
Confidence
84% confidence
Finding

flatted 3.3.3 has reported denial-of-service and prototype-pollution issues in parse() handling, which can be dangerous when deserializing attacker-controlled data. In this lockfile it appears only as a transitive devDependency of flat-cache used by ESLint, so the skill context makes exploitation less direct, but it remains a real supply-chain weakness if malicious input reaches the parser during development or CI workflows.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: js-yaml==4.1.1 — 4 advisory(ies): CVE-2026-84375 (js-yaml: maxTotalMergeKeys does not limit CPU use for empty merge sources); CVE-2026-59869 (js-yaml: YAML merge-key chains can force quadratic CPU consumption); GHSA-5p4m-2wfm-xmqj (JS-YAML: Quadratic CPU consumption in !!omap resolution (3.x and 4.x) — CVE-2026) +1 more

High
Category
Supply Chain
Confidence
90% confidence
Finding

js-yaml 4.1.1 has multiple reported CPU-consumption denial-of-service issues involving merge keys and complex YAML structures. Although this instance is a devDependency used through ESLint configuration handling rather than obvious production code, parsing attacker-controlled YAML in developer or CI contexts could still hang processes or exhaust CPU.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: minimatch==3.1.2 — 3 advisory(ies): CVE-2026-27904 (minimatch ReDoS: nested *() extglobs generate catastrophically backtracking regu); CVE-2026-26996 (minimatch has a ReDoS via repeated wildcards with non-matching literal in patter); CVE-2026-27903 (minimatch has ReDoS: matchOne() combinatorial backtracking via multiple non-adja)

High
Category
Supply Chain
Confidence
91% confidence
Finding

minimatch 3.1.2 has several reported ReDoS issues where crafted glob patterns can trigger catastrophic backtracking and excessive CPU use. In this skill the package is transitive through development tooling, so it is less dangerous than a runtime dependency, but it is still a true vulnerability if untrusted patterns can reach linting, globbing, cleanup, or CI tasks.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README provides copy-pasteable code to open and close trading positions automatically, but it does not prominently warn that these actions can trigger real or simulated order execution with financial consequences, API credential use, and strategy risk. In an agent skill context, examples are often treated as safe defaults, so omission of explicit risk and confirmation guidance increases the chance of unintended automated trading behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The openPosition method submits a POST request that creates a new trading position, which is a safety-critical action affecting portfolio state. While there is internal logging, there is no confirmation prompt or user-facing warning before the trade is placed, and the brief docstring does not disclose the risk of executing a position.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The closePosition method performs a POST request to close an open position, which directly changes trading state and may realize profit or loss. The code logs after the fact, but it does not provide any confirmation or advance disclosure that invoking this method will immediately close the position.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The header comment says the strategy 'trades stocks that moved >20%' and 'shorts extreme gainers,' which implies entry logic based on market movement. However, the code never fetches market movers or opens/shorts positions; it only reads current positions, closes profitable ones, and logs portfolio status.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ajv==6.12.6 — 1 advisory(ies): CVE-2025-69873 (ajv has ReDoS when using `$data` option)

Low
Category
Supply Chain
Confidence
75% confidence
Finding

The lockfile includes ajv 6.12.6, which has a reported ReDoS condition when the optional $data feature is enabled on attacker-controlled schemas or inputs. In this file it is a transitive devDependency via ESLint tooling, so exposure is limited and there is no evidence from the lockfile alone that the vulnerable option is used at runtime.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 24)May include surrounding context.

json
"author": "Molt Trader",
  "license": "MIT",
  "dependencies": {
    "@trpc/client": "^11.0.0",
    "@trpc/server": "^11.0.0",
    "superjson": "^2.2.1"
  },

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 25)May include surrounding context.

json
"license": "MIT",
  "dependencies": {
    "@trpc/client": "^11.0.0",
    "@trpc/server": "^11.0.0",
    "superjson": "^2.2.1"
  },
  "devDependencies": {

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 26)May include surrounding context.

json
"dependencies": {
    "@trpc/client": "^11.0.0",
    "@trpc/server": "^11.0.0",
    "superjson": "^2.2.1"
  },
  "devDependencies": {
    "@types/node": "^20.0.0",

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 29)May include surrounding context.

json
"superjson": "^2.2.1"
  },
  "devDependencies": {
    "@types/node": "^20.0.0",
    "typescript": "^5.3.0",
    "eslint": "^8.0.0"
  },

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 30)May include surrounding context.

json
},
  "devDependencies": {
    "@types/node": "^20.0.0",
    "typescript": "^5.3.0",
    "eslint": "^8.0.0"
  },
  "engines": {

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 31)May include surrounding context.

json
"devDependencies": {
    "@types/node": "^20.0.0",
    "typescript": "^5.3.0",
    "eslint": "^8.0.0"
  },
  "engines": {
    "node": ">=18.0.0"

Static analysis

No suspicious patterns detected.