Back to skill

Security audit

valuescan-monitor-skill

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed ValueScan monitoring tool, but it handles API credentials and continuous file writes with enough scoping and validation gaps that users should review it before installing.

Install only if you are comfortable storing ValueScan API credentials in ~/.vs-monitor/config.json and running long-lived background processes. Use a restricted account or container, lock down ~/.vs-monitor permissions, keep endpoints set to the documented ValueScan hosts, avoid all-token monitoring unless needed, and review or patch filename validation before using untrusted streams.

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
script/monitor.py:62
Finding

Configurable Network Endpoints Can Receive Authentication Material

Content
View full analysis
list: """Convert token symbols (e.g. 'BTC') to vsTokenId strings.""" token_ids = [] for symbol in symbols: body = json.dumps({"search": symbol}) headers = build_api_headers(api_key, secret_key, body) try: resp = requests.post( f"{api_base_url}/api/open/v1/vs-token/list", headers=headers, data=body, timeout=10, ) ``` ```python def run_market(config: dict) -> None: stream_base = config.get("streamBaseUrl", "https://stream.valuescan.ai") output_dir = config["outputDir"] params = build_stream_params(config["apiKey"], config["secretKey"]) resp = requests.get( f"{stream_base}/stream/market/subscribe", params=params, stream=True, timeout=None, ) ``` ```typescript async function resolveTokenIds(symbols: string[], apiKey: string, secretKey: string, apiBaseUrl: string): Promise { const tokenIds: string[] = []; for (const symbol of symbols) { const body = JSON.stringify({ search: symbol }); const headers = buildApiHeaders(apiKey, secretKey, body); try { const resp = await fetch(`${apiBaseUrl}/api/open/v1/vs-token/list`, { method: 'POST', headers, body, }); ``` ```typescript function runMarket(config: Config): void { const base = config.streamBaseUrl ?? 'https://stream.valuescan.ai'; const url = buildStreamUrl(base, '/stream/market/subscribe', config.apiKey, config.secretKey); const es = new EventSource(url); ``` ### Technical Analysis The API and stream base URL ...[truncated 1950 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
script/monitor.py:98
Finding

Remote Signal Symbols Permit Path Traversal During File Creation

Content
View full analysis
None: msg = json.loads(payload) signal_type = msg.get("type", "UNKNOWN") try: inner = json.loads(msg.get("content", "{}")) except Exception: inner = {} symbol = inner.get("symbol", "UNKNOWN") content = msg.get("content", "") now = datetime.now() dir_path = Path(output_dir) / "代币信号" / now.strftime("%Y-%m-%d") dir_path.mkdir(parents=True, exist_ok=True) file_path = dir_path / f"{symbol}.txt" with open(file_path, "a", encoding="utf-8") as f: f.write(f"[{now.strftime('%H:%M:%S')}] [{signal_type}]\n{content}\n---\n") ``` ```typescript function writeSignal(payload: string, outputDir: string): void { const msg = JSON.parse(payload) as { type: string; content: string }; let inner: { symbol?: string } = {}; try { inner = JSON.parse(msg.content); } catch { /* ignore */ } const symbol = inner.symbol ?? 'UNKNOWN'; const now = new Date(); const dateStr = now.toISOString().slice(0, 10); const timeStr = now.toTimeString().slice(0, 8); const dir = path.join(outputDir, '代币信号', dateStr); fs.mkdirSync(dir, { recursive: true }); fs.appendFileSync(path.join(dir, `${symbol}.txt`), `[${timeStr}] [${msg.type}]\n${msg.content}\n---\n`, 'utf-8'); } ``` ### Technical Analysis The `symbol` value originates in an SSE message received from a remote server. Both implementations concatenate that value into a file path without validating it as a safe filename. Path APIs do not automatically confine a resulting path to the intended directory. A value containing traversal components such as `../` can escape the date-specific signal directory. The scripts open the resulting path in append mode, allowin ...[truncated 1672 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:25
Finding

API Credentials Are Persisted in Plaintext Without Enforced File Permissions

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
script/package.json:8
Finding

Unpinned Third-Party Dependencies Create Supply-Chain Exposure

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (23)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The documented purpose understates the skill's authenticated network behavior and credential usage, including HMAC signing and additional API access. When a skill's declared role does not fully disclose how credentials are used, operators may grant trust or deploy it in contexts without understanding its true data exposure and network reach.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The documented purpose understates the skill's authenticated network behavior and credential usage, including HMAC signing and additional API access. When a skill's declared role does not fully disclose how credentials are used, operators may grant trust or deploy it in contexts without understanding its true data exposure and network reach.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding

The skill clearly performs network access and local file writes, yet it declares no explicit tool scope or permissions boundary. This creates an authorization gap where a user or host may not realize the skill can persist data and make authenticated outbound connections, increasing the chance of overbroad execution and unsafe deployment.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest description and all operational instructions are written exclusively in Chinese, and the trigger phrases are also Chinese-only. There is no indication that the skill supports language choice or that the Chinese-only constraint is a documented, justified regional requirement, which can violate language/locale policy expectations.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
81% confidence
Finding

The skill is designed to create persistent background processes with nohup and manage them via PID files, extending execution beyond the initiating session. In combination with network access, local file writes, and stored credentials, persistent unattended execution increases the blast radius of misconfiguration, compromise, or misuse.

Content

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

后台启动:

bash
nohup python /path/to/vs-monitor-skill/script/monitor.py --market \
    --config=~/.vs-monitor/config.json > ~/.vs-monitor/market.log 2>&1 &
echo $! > ~/.vs-monitor/market.pid

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

Using npx ts-node without a pinned version allows execution of whatever package version resolves at runtime, which can change over time or be affected by supply-chain compromise. In a skill that processes credentials and network streams, this creates a realistic path to arbitrary code execution under the user's account.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

This second npx ts-node invocation has the same supply-chain risk as the prior one: it may fetch or run an unexpected version at execution time. Because the skill also handles API secrets and long-running background monitoring, compromise of this execution path could expose credentials and tamper with persisted output.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

This manifest-style JSON states that if the tokens parameter is not provided, the subscription defaults to all token signals. For a trigger or activation description, this is broad and lacks negative examples or clearer scope boundaries, which could cause unintended full-stream subscriptions rather than a narrowly targeted one.

Content

No source excerpt is available for this finding.

Unbounded Resource Access

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.

Content

Scanner excerpt · script/monitor.py (reported line 151)May include surrounding context.

python
f"{stream_base}/stream/market/subscribe",
        params=params,
        stream=True,
        timeout=None,
    )
    resp.raise_for_status()
    for event in sseclient.SSEClient(resp).events():

Unbounded Resource Access

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.

Content

Scanner excerpt · script/monitor.py (reported line 172)May include surrounding context.

python
f"{stream_base}/stream/market/subscribe",
        params=params,
        stream=True,
        timeout=None,
    )
    resp.raise_for_status()
    for event in sseclient.SSEClient(resp).events():

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
84% confidence
Finding

The script loads apiKey and secretKey from config, uses them to sign requests, and sends authenticated network traffic to external ValueScan endpoints. While network access is central to the script's purpose, there is no visible disclosure in the file that local credentials will be read from disk and used for outbound authenticated connections.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script persistently writes all streamed market and signal content to local files under a user-configured directory, but provides no runtime disclosure, confirmation, retention policy, or visibility into where data is stored. In a monitoring skill, silent ongoing persistence can expose sensitive trading signals or proprietary feed data to other local users, backups, or later unintended processing.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

All user-facing names, descriptions, parameter explanations, and event descriptions in this file are written only in Chinese, with no indication that language selection is optional or region-specific. This can violate a language/locale policy when a skill implicitly enforces one language without user opt-in or documented justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code forces Chinese-language directory names and file prefixes such as '大盘分析' and '代币信号' for all users. There is no option to choose a language or locale, and no justification that this is a region-specific tool, which creates a natural-language locale policy concern.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
90% confidence
Finding

The production dependency uses a caret range, which allows newer minor/patch releases to be installed than the one originally tested. This weakens build reproducibility and can unintentionally pull in a vulnerable or breaking upstream version, which is more relevant here because this skill ingests external stream data and writes locally, making supply-chain hygiene important.

Content

Scanner excerpt · script/package.json (reported line 9)May include surrounding context.

json
"monitor": "ts-node monitor.ts"
  },
  "dependencies": {
    "eventsource": "^2.0.2"
  },
  "devDependencies": {
    "@types/eventsource": "^1.1.15",

Unverifiable Dependency: eventsource has 1 known advisory(ies) (CVE-2022-1650 (Exposure of Sensitive Information in eventsource)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
91% confidence
Finding

The manifest references eventsource with a non-exact version while that package has a known advisory history, so it is not possible to verify from this file whether the resolved version is affected. In this skill, eventsource is a runtime dependency used to consume external stream data, so an affected version could expose sensitive information or otherwise increase risk in a network-facing component.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
82% confidence
Finding

The dev dependency is version-ranged with a caret, so development and CI environments may resolve different package versions over time. While this is less dangerous than an unpinned runtime dependency, it still creates supply-chain and reproducibility risk, especially if CI executes tooling from devDependencies.

Content

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

json
"eventsource": "^2.0.2"
  },
  "devDependencies": {
    "@types/eventsource": "^1.1.15",
    "@types/node": "^20.0.0",
    "ts-node": "^10.9.2",
    "typescript": "^5.0.0"

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
82% confidence
Finding

Using a caret range for @types/node allows silent dependency drift across environments. This is mainly a reproducibility and supply-chain integrity concern rather than a direct code-execution flaw, but it can still affect builds and tooling trustworthiness.

Content

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

json
},
  "devDependencies": {
    "@types/eventsource": "^1.1.15",
    "@types/node": "^20.0.0",
    "ts-node": "^10.9.2",
    "typescript": "^5.0.0"
  }

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
88% confidence
Finding

The ts-node dev dependency is unpinned, and this package is executable tooling that can run TypeScript directly in development or CI. If a malicious or compromised upstream release is resolved, it could execute during build or monitoring workflows, making this somewhat more sensitive than type-only packages.

Content

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

json
"devDependencies": {
    "@types/eventsource": "^1.1.15",
    "@types/node": "^20.0.0",
    "ts-node": "^10.9.2",
    "typescript": "^5.0.0"
  }
}

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
84% confidence
Finding

The typescript package is version-ranged, which permits unreviewed compiler updates to enter builds. This primarily introduces supply-chain and reproducibility risk, and in CI environments compiler/tooling compromise could affect generated artifacts or build-time execution paths.

Content

Scanner excerpt · script/package.json (reported line 15)May include surrounding context.

json
"@types/eventsource": "^1.1.15",
    "@types/node": "^20.0.0",
    "ts-node": "^10.9.2",
    "typescript": "^5.0.0"
  }
}

Static analysis

No suspicious patterns detected.