Back to skill

Security audit

Stocktoday Skill

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches a stock-market data purpose, but it automatically runs unpinned npx code and has weak API-token transport/scoping controls that warrant Review before installation.

Install only if you are comfortable with this skill contacting StockToday backends using your API token and writing a local token-status cache. Prefer HTTPS-only backend configuration, protect and rotate the token if exposed, and avoid running the unpinned npx install/update commands in sensitive environments until the publisher removes the automatic npx version check and plaintext HTTP fallback endpoints.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
src/index.ts:15
Finding

API token can be transmitted over plaintext HTTP

Content
View full analysis

Vulnerability Details

File Location: src/index.ts:15-17, src/index.ts:247-260, and src/index.ts:298-302
Vulnerability Type: Plaintext transmission of sensitive credentials
Risk Level: High

Vulnerable Code

ts
const BACKUP_URL1 = process.env.STOCKTODAY_BACKUP_URL1 || "http://111.229.164.2:8083/";
const BACKUP_URL2 = process.env.STOCKTODAY_BACKUP_URL2 || "http://124.223.112.152:6331/";
const BACKUP_URL3 = process.env.STOCKTODAY_BACKUP_URL3 || "http://110.42.211.9:9900/";
ts
async function fetchOne(url: string, endpoint: string, formData: URLSearchParams): Promise<{status: number; data: any; raw: string}> {
  try {
    const res = await fetch(`${url}${endpoint}`, {
      method: "POST",
      body: formData,
      headers: {
        "Content-Type": "application/x-www-form-urlencoded",
        "X-Client-Type": "StockToday-skill",
        "X-Client-Version": "1.3.11"
      },
      signal: AbortSignal.timeout(30000)
    });
    const raw = await res.text();
    let data: any;
    try { data = JSON.parse(raw); } catch { data = raw; }
    return { status: res.status, data, raw };
  } catch (e: any) {
    return { status: 0, data: null, raw: e?.message || String(e) };
  }
}
ts
const formData = new URLSearchParams();
formData.append("TOKEN", token);

const urls = [BASE_URL, BACKUP_URL1, BACKUP_URL2, BACKUP_URL3];

Technical Analysis

The API credential is included in a URL-encoded POST body for every backend request. The Skill defines three default fallback gateways using unencrypted HTTP and does not enforce an HTTPS-only policy for either the primary URL or fallback URLs.

Any request sent to an HTTP endpoint exposes the token and response data to network observers and active intermediaries. Encryption is especially important here because possession of the token is sufficient to authenticate API requests.

The current fallback loop ...[truncated 1532 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove all default plaintext HTTP fallback gateways.
  2. Require every configured backend URL to use the https: protocol:
    ts
    function requireHttps(raw: string): string {
      const parsed = new URL(raw);
      if (parsed.protocol !== "https:") {
        throw new Error("StockToday backend URLs must use HTTPS");
      }
      return parsed.toString();
    }
    
  3. Apply this validation to STOCKTODAY_URL and every configured fallback URL before processing requests.
  4. Replace bare IP addresses with authenticated HTTPS domain names whose certificates can be validated.
  5. Do not provide an option to disable TLS certificate validation.
  6. Correct the fallback loop separately so that only genuine transport failures or retryable responses cause failover, while preserving the HTTPS-only requirement.
  7. Rotate any token that may previously have been sent to an HTTP endpoint.
  8. Document the exact backend domains that receive tokens and allow administrators to enforce an outbound network allowlist.

T03 · Remote Payload Retrieval and Execution

Warning
Location
src/index.ts:114
Finding

Automatic unpinned npx package execution during Skill startup

Content
View full analysis

Vulnerability Details

File Location: src/index.ts:114-127 and src/index.ts:978-984
Vulnerability Type: Unpinned remote package resolution and execution
Risk Level: Medium

Vulnerable Code

ts
async function checkClawhubLatest(): Promise<string | null> {
  return new Promise((resolve) => {
    // Windows 上 npx 是 .cmd, 需要 shell:true 避免 EINVAL
    const isWin = process.platform === "win32";
    const cmd = isWin ? "npx.cmd" : "npx";
    const opts: any = { timeout: 12000, shell: isWin };
    execFile(cmd, ["clawhub", "info", "stocktoday-skill"], opts, (err, stdout, stderr) => {
      if (err) { resolve(null); return; }
      const out = String(stdout || "") + String(stderr || "");
      const m = out.match(/(?:version|latest|Version|Latest)\s*[::]?\s*v?(\d+\.\d+\.\d+)/);
      if (m) { resolve(m[1]); return; }
      const m2 = out.match(/(\d+\.\d+\.\d+)/);
      resolve(m2 ? m2[1] : null);
    });
  });
}
ts
// 启动后 2s 检查 ClawHub 最新版本 (非阻塞, 10s 超时)
setTimeout(() => {
  refreshUpdateNotice().catch(e =>
    console.error("[update] check failed:", e.message)
  );
}, 2000).unref();

// 每 24h 重新检查 (避免频繁扰动 ClawHub)
setInterval(() => {
  refreshUpdateNotice().catch(() => {});
}, 24 * 60 * 60 * 1000).unref();

Technical Analysis

Starting the MCP server schedules execution of npx clawhub info stocktoday-skill, and the command runs again every 24 hours. The invoked package is not resolved from a version-pinned project dependency or an integrity-verified local path.

Depending on the local npm/npx configuration, if the requested executable is not already available, npx can resolve and execute package content obtained from a package registry. Consequently, the effective code executed by the Skill may change after the audited package was published. Compromise of the upstream package, registry account, package-resolution process, or loca ...[truncated 1747 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove the automatic npx subprocess from startup and periodic execution.
  2. If update checking is required, retrieve non-executable version metadata from a fixed HTTPS endpoint and validate a signed response.
  3. Alternatively, declare the required CLI as a project dependency with an exact version in package.json and a committed integrity-locked package-lock.json.
  4. Resolve and invoke only the expected local binary under node_modules/.bin; do not permit runtime package installation or registry resolution.
  5. Verify the resolved binary path before execution and avoid relying on the ambient PATH.
  6. Avoid shell: true on every platform. If Windows compatibility requires special handling, invoke a fixed local script through a known Node.js executable rather than a command shell.
  7. Make update checks opt-in and disabled by default.
  8. Perform upgrades only through an explicit user action rather than injecting upgrade prompts into normal tool responses.
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 (63)

MCP Config Access

High
Category
Agent Snooping
Confidence
95% confidence
Finding

Skill accesses MCP server configuration files (mcp.json). MCP configs contain server URLs, authentication tokens, and tool definitions — reading them allows the skill to discover and potentially abuse other tool integrations.

Content

Scanner excerpt · INSTALL.md (reported line 73)May include surrounding context.

4.1 Claude Code (CLI)

配置文件: ~/.claude/mcp.json (用户级) 或 .mcp.json (项目级)

bash
# 1) 安装

MCP Config Access

High
Category
Agent Snooping
Confidence
95% confidence
Finding

Skill accesses MCP server configuration files (mcp.json). MCP configs contain server URLs, authentication tokens, and tool definitions — reading them allows the skill to discover and potentially abuse other tool integrations.

Content

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

4.1 Claude Code (CLI)

配置文件: ~/.claude/mcp.json (用户级) 或 .mcp.json (项目级)

bash
# 1) 安装

MCP Config Access

High
Category
Agent Snooping
Confidence
95% confidence
Finding

Skill accesses MCP server configuration files (mcp.json). MCP configs contain server URLs, authentication tokens, and tool definitions — reading them allows the skill to discover and potentially abuse other tool integrations.

Content

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

4.1 Claude Code (CLI)

配置文件: ~/.claude/mcp.json (用户级) 或 .mcp.json (项目级)

bash
# 1) 安装

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The file claims there are no sensitive information leaks, yet it discloses an admin key (612526198902030050) and internal infrastructure details including database identifiers and admin endpoints. This is dangerous because anyone reading the notes could attempt privileged actions such as unblocking rate limits or probing internal services, turning documentation into a credential leak.

Content

No source excerpt is available for this finding.

MCP Config Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

Skill accesses MCP server configuration files (mcp.json). MCP configs contain server URLs, authentication tokens, and tool definitions — reading them allows the skill to discover and potentially abuse other tool integrations.

Content

Scanner excerpt · RELEASE_NOTES.md (reported line 80)May include surrounding context.

md
### 兼容性
- ✅ 100% 向后兼容 (241 工具数不变)
- ✅ 所有废弃/已死接口只标 desc, 不删接口 (避免破坏现有调用)
- ✅ env 变量无任何硬编码 token, 用户 .mcp.json 配 STOCKTODAY_TOKEN 即可

---

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The token_info tool is described as only allowing a user to query their own token, but the handler uses const token = params.token || TOKEN, meaning a caller can supply any token value. This enables token probing/validation against the remote /TOKEN endpoint and may disclose account metadata such as validity, permissions, plugins, and expiry for arbitrary tokens if known or guessed.

Content

No source excerpt is available for this finding.

MCP Config Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

Skill accesses MCP server configuration files (mcp.json). MCP configs contain server URLs, authentication tokens, and tool definitions — reading them allows the skill to discover and potentially abuse other tool integrations.

Content

Scanner excerpt · dist/token_breaker.js (reported line 38)May include surrounding context.

js
return {
                open: false,
                state: 'CLOSED',
                message: '⚠️ token 似乎无效, 暂停 30s 防止触发 IP ban. 请检查 .mcp.json 里的 STOCKTODAY_TOKEN (从 https://stocktoday.cn 申请)',
                failCount: this.failCount,
            };
        }

MCP Config Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

Skill accesses MCP server configuration files (mcp.json). MCP configs contain server URLs, authentication tokens, and tool definitions — reading them allows the skill to discover and potentially abuse other tool integrations.

Content

Scanner excerpt · src/token_breaker.ts (reported line 47)May include surrounding context.

ts
return {
                open: false,
                state: 'CLOSED',
                message: '⚠️ token 似乎无效, 暂停 30s 防止触发 IP ban. 请检查 .mcp.json 里的 STOCKTODAY_TOKEN (从 https://stocktoday.cn 申请)',
                failCount: this.failCount,
            };
        }

Known Vulnerable Dependency: fast-uri==3.1.2 — 6 advisory(ies): CVE-2026-13676 (fast-uri vulnerable to host confusion via failed IDN canonicalization); CVE-2026-18446 (fast-uri vulnerable to host confusion via backslash authority introducer); CVE-2026-75975 (fast-uri vulnerable to server-side request forgery via malformed IPv6 normalizat) +3 more

High
Category
Supply Chain
Confidence
80% confidence
Finding

fast-uri 3.1.2 is flagged for multiple URI parsing and host confusion issues that can lead to SSRF or policy bypass when applications make security decisions from parsed URLs. In a skill ecosystem, URL parsing bugs are particularly relevant because MCP skills often consume remote endpoints or validate callback/origin URLs, so a vulnerable parser can undermine network trust boundaries even if the flaw is only transitively included.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ip-address==10.2.0 — 3 advisory(ies): CVE-2026-54272 (ip-address: misclassification of IPv4-mapped/NAT64 IPv6 addresses can bypass SSR); CVE-2026-69198 (ip-address: a CIDR suffix on the parsed address suppresses special-use classific); CVE-2026-69192 (ip-address: Address4 decodes leading-zero octets as decimal while resolvers deco)

High
Category
Supply Chain
Confidence
84% confidence
Finding

ip-address 10.2.0 is flagged for address parsing and classification flaws that can cause SSRF filters or network access controls to misclassify special-use or mapped addresses. This is especially concerning in agent skills because they may enforce internal-network blocking or hostname/IP validation before outbound requests, and a parsing bug can allow access to internal services or metadata endpoints.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The tool description says token_info can only query the caller's own token, but the implementation accepts params.token || TOKEN, allowing any supplied token to be sent to /TOKEN. This can let a user probe arbitrary tokens' validity, expiry, permissions, and plugin access if they possess or guess tokens, violating the stated trust boundary.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

The guide tells users to execute npx clawhub install stocktoday without pinning the package manager invocation to a specific trusted version. npx resolves and runs remote code at install time, so a compromised or maliciously updated package or dependency could lead to arbitrary code execution on the user's machine.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

Although the skill version is pinned here, the executable being fetched and run is still clawhub via unpinned npx. That leaves users exposed to arbitrary code execution if the latest clawhub package or its dependencies are tampered with.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

This command again relies on unpinned npx clawhub, which executes code retrieved from the package ecosystem. Because --force may overwrite an existing installation, compromise of the installer could have broader local impact by replacing trusted files.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The guide instructs users to place the API token directly into environment variables and MCP config files without warning that the token is a credential that must be protected. Storing secrets in plaintext config files increases the chance of accidental exposure through screenshots, shell history, backups, logs, version control, or multi-user system access.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
94% confidence
Finding

The Claude Code integration section repeats the unpinned npx clawhub install stocktoday pattern. Any installation instruction that causes users to fetch and execute a mutable remote package is a supply-chain risk, especially in documentation intended for broad copy-paste use.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

The upgrade command fetches the latest clawhub package at runtime and then performs an update operation, creating a supply-chain execution path. Users following this guidance could run attacker-controlled code if the package namespace or dependency chain is compromised.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

This command pins the skill version but not the clawhub executable that will be downloaded and run. That still allows a malicious or compromised installer version to execute arbitrary code during the update process.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
94% confidence
Finding

The uninstall instruction also uses unpinned npx clawhub, meaning even removal triggers execution of an untrusted mutable package. Attackers often exploit maintenance commands because users are less suspicious when uninstalling or troubleshooting.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The advanced configuration documents multiple remote backend URLs, including plaintext HTTP backup endpoints, but does not clearly warn users that the skill will transmit token-authenticated requests to external services. This obscures the data flow and, for the HTTP backups, creates a risk of credential interception or traffic tampering by network attackers.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README instructs users to place STOCKTODAY_TOKEN directly into configuration and environment variable examples but does not warn that the token is a secret that must not be committed, shared, logged, or pasted into screenshots. This omission increases the chance of credential leakage through dotfiles, repositories, support requests, or terminal history, which could allow unauthorized use of the user's account and quota.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access, suspicious.potential_exfiltration

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
src/index.ts:125

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
dist/index.js:45

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
src/index.ts:11

Sensitive-looking file read is paired with a network send.

Warn
Code
suspicious.potential_exfiltration
Location
dist/index.js:72

Sensitive-looking file read is paired with a network send.

Warn
Code
suspicious.potential_exfiltration
Location
src/index.ts:43