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## 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
## 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## 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
## 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
Content
### 4.1 Claude Code (CLI)

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

```bash
# 1) 安装
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.

MCP Config Access

High
Category
Agent Snooping
Content
### 4.1 Claude Code (CLI)

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

```bash
# 1) 安装
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.

MCP Config Access

High
Category
Agent Snooping
Content
### 4.1 Claude Code (CLI)

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

```bash
# 1) 安装
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.

Intent-Code Divergence

High
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.

MCP Config Access

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

---
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.

Intent-Code Divergence

High
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.

MCP Config Access

High
Category
Agent Snooping
Content
return {
                open: false,
                state: 'CLOSED',
                message: '⚠️ token 似乎无效, 暂停 30s 防止触发 IP ban. 请检查 .mcp.json 里的 STOCKTODAY_TOKEN (从 https://stocktoday.cn 申请)',
                failCount: this.failCount,
            };
        }
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.

MCP Config Access

High
Category
Agent Snooping
Content
return {
                open: false,
                state: 'CLOSED',
                message: '⚠️ token 似乎无效, 暂停 30s 防止触发 IP ban. 请检查 .mcp.json 里的 STOCKTODAY_TOKEN (从 https://stocktoday.cn 申请)',
                failCount: this.failCount,
            };
        }
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.

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.

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.

Intent-Code Divergence

High
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.

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.

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.

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.

Missing User Warnings

Medium
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.

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.

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.

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.

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.

Missing User Warnings

Medium
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.

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.

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.

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.

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.

Missing User Warnings

Medium
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.

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