Back to skill

Security audit

BTC短线预测

Security checks for vulnerabilities and agentic risk

Overview

This BTC prediction skill mostly does what it advertises, but its paid billing flow is under-scoped and unsafe enough that users should review it carefully before installing.

Install only if you are comfortable with a paid remote billing service being contacted on invocation. Treat the bundled SkillPay key as exposed, do not rely on the advertised win-rate or automated-trading claims, and avoid using the history or auto commands until billing is validated before charging.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/skillpay.js:6
Finding
Hardcoded Billing API Credential Exposed in Source Code<![CDATA[ ## Vulnerability Details **File Location**: `scripts/skillpay.js:6-7, 20-28, 49-57` **Vulnerability Type**: Hardcoded secret and sensitive credential transmission **Risk Level**: High ### Vulnerable Code ```js const BILLING_API_URL = 'https://skillpay.me'; const BILLING_API_KEY = process.env.SKILLPAY_API_KEY || 'sk_a267a27a1eb8381a762a9a6cdb1ea7d722f9f45f345b7319cfd3cccd9fae35c5'; const SKILL_ID = '0525333e-9ef5-4c67-ac65-1463a8ca3d65'; async function chargeUser(userId, amount = 0.005) { const resp = await fetch(`${BILLING_API_URL}/api/v1/billing/charge`, { method: 'POST', headers: { 'X-API-Key': BILLING_API_KEY, 'Content-Type': 'application/json', }, body: JSON.stringify({ user_id: userId, skill_id: SKILL_ID, amount: amount, }), }); } async function getPaymentLink(userId, amount = 8) { const resp = await fetch(`${BILLING_API_URL}/api/v1/billing/payment-link`, { method: 'POST', headers: { 'X-API-Key': BILLING_API_KEY, 'Content-Type': 'application/json', }, body: JSON.stringify({ user_id: userId, amount, }), }); } ``` ### Technical Analysis The source contains a complete fallback billing API key. When `SKILLPAY_API_KEY` is absent, the embedded credential is automatically placed in the `X-API-Key` header and sent to `https://skillpay.me`. Sending a billing credential to its declared HTTPS service is necessary for the selected client-side billing design. However, distributing a reusable credential in source code is not necessary and violates secret-management and least-privilege principles. Anyone who can read the package can extract the credential and use it outside the Skill. HTTPS protects the credential in transit but does not address disclosure from the source package. The exact operations available to the credential depend on server-side authorization. The observed client uses it for charge and payment-link requests. ### Attack Path 1. A ...[truncated 1137 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Immediately revoke and rotate the exposed API key. 2. Remove the fallback credential from source code and version history. 3. Require `SKILLPAY_API_KEY` to be supplied through an approved secret-management mechanism and fail closed when it is missing. 4. Prefer a server-side billing broker so merchant credentials are never distributed to Skill clients. 5. If client credentials are unavoidable, issue short-lived, narrowly scoped, revocable tokens restricted to: - The expected Skill identifier - Fixed or server-validated charge amounts - Specific billing endpoints - An authenticated user identity 6. Enforce authorization and request validation on the billing server rather than trusting client-submitted `user_id`, `skill_id`, or `amount`. 7. Add secret scanning to CI and pre-commit workflows to prevent future credential publication. 8. Avoid logging API keys, authorization headers, or complete billing responses. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/predict.js:80
Finding
Billing Identity Is Generated from an Unauthenticated Timestamp<![CDATA[ ## Vulnerability Details **File Location**: `scripts/predict.js:80-94` **Vulnerability Type**: Insecure billing identity and authorization design **Risk Level**: Medium ### Vulnerable Code ```js const userId = 'user_' + Date.now(); // Charge the user console.log('\n⏳ 检查余额并扣费...'); const chargeResult = await chargeUser(userId, SKILL_PRICE); if (!chargeResult.ok) { console.log('\n❌ 余额不足'); console.log(`当前余额: ${chargeResult.balance} USDT`); console.log('\n💳 请充值后继续:'); const paymentUrl = await getPaymentLink(userId, 8); console.log(paymentUrl); process.exit(1); } ``` ### Technical Analysis The billing identity is derived solely from the local timestamp: ```js const userId = 'user_' + Date.now(); ``` This value is neither authenticated nor persistent. Each process invocation normally produces a different identity, and users can also choose arbitrary equivalent values by directly invoking the exported billing functions or calling the remote API with the exposed credential. A billing identity should be issued by, or cryptographically bound to, an authenticated account. A client-generated timestamp provides no proof that the caller owns the associated balance. It also breaks continuity between a payment link generated during one invocation and a charge attempted during a later invocation. ### Attack Path A reproducible billing-continuity failure is: 1. A user invokes the Skill with insufficient balance. 2. The client generates an identifier such as `user_1750000000000`. 3. The program creates and displays a payment link associated with that identifier. 4. The user funds the identifier through the link. 5. The user invokes the Skill again. 6. The second process generates a different timestamp-based identifier. 7. The client checks and attempts to charge the new identifier rather than the previously funded one. If the server trusts arbitrary `user_id` fields without authenticating ownership, an attacker could also submit another predi ...[truncated 621 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the timestamp-derived identifier with a stable identity issued by the billing provider. 2. Require users to authenticate before generating payment links or submitting charges. 3. Bind the user identity to a signed, short-lived session token that the client cannot modify. 4. Persist the authorized billing identity securely so subsequent invocations use the same account. 5. Enforce ownership, amount, Skill ID, and replay validation on the billing server. 6. Use idempotency keys for charge operations to prevent duplicate billing during retries. 7. Do not expose raw billing identifiers when an opaque, provider-issued account reference can be used. 8. Add tests confirming that a payment made through one invocation remains available during later invocations. ]]>

other

Warning
Location
scripts/predict.js:62
Finding
Unsupported Documented Commands Enter the Paid Prediction Workflow<![CDATA[ ## Vulnerability Details **File Location**: `scripts/predict.js:62-83` **Related Documentation**: `SKILL.md:29-33` **Vulnerability Type**: Billing integrity and functional misrepresentation **Risk Level**: Medium ### Vulnerable Code The documentation advertises separate history and automatic modes: ```bash # Get the current prediction node scripts/predict.js # View historical results node scripts/predict.js history # Automatic mode, predicting every 15 minutes node scripts/predict.js auto ``` The implementation only recognizes `help` before entering the charging workflow: ```js async function main() { const args = process.argv.slice(2); if (args.length > 0 && args[0] === 'help') { console.log(` ╔════════════════════════════════════════════════════════╗ ║ BTC 短线预测器 - 15分钟级别涨跌预测 ║ ║ 每次调用 0.005 USDT ║ ╚════════════════════════════════════════════════════════╝ 用法: node predict.js [命令] 命令: (无参数) 获取当前预测 history 查看历史战绩(开发中) auto 自动模式(开发中) 示例: node predict.js 💰 支付: BNB Chain USDT,最低充值 8 USDT `); process.exit(0); } const userId = 'user_' + Date.now(); // 扣费 console.log('\n⏳ 检查余额并扣费...'); const chargeResult = await chargeUser(userId, SKILL_PRICE); ``` ### Technical Analysis There is no command-dispatch branch for `history` or `auto`. Only `help` receives special handling. Consequently, both documented commands—and any other unrecognized argument—fall through to the ordinary one-shot charge and prediction path. The `history` command therefore does not display historical results, and `auto` does not schedule a prediction every 15 minutes. Both can still initiate a charge attempt. This violates the expectation that billing occurs only after the requested operation has been validated and can be delivered. ### Attack Path 1. A user follows the documented instructions and runs `node scripts/predict.js history` or `node scripts/predict.js auto`. ...[truncated 909 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Implement explicit command dispatch before any billing operation. 2. Reject unknown or unsupported commands with a non-billing error. 3. Do not charge for `history` or `auto` until those operations are fully implemented and validated. 4. Remove unsupported commands from `SKILL.md` and help text if they will not be implemented. 5. Display the exact operation and price, then obtain clear confirmation before initiating a charge where interactive use permits. 6. Couple each charge to a server-validated operation identifier and issue refunds automatically when the requested operation fails. 7. Add tests verifying that: - `help` never charges. - Unknown commands never charge. - `history` performs only its documented behavior. - `auto` either starts the documented mode or fails without charging. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (15)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill appears to access an external billing API and use credentials while presenting itself primarily as a BTC predictor. Undisclosed external billing integration and credential-dependent behavior increase the risk of unauthorized charging, opaque data flows, and misuse of secrets, especially in a financial context.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill appears to access an external billing API and use credentials while presenting itself primarily as a BTC predictor. Undisclosed external billing integration and credential-dependent behavior increase the risk of unauthorized charging, opaque data flows, and misuse of secrets, especially in a financial context.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill appears to access an external billing API and use credentials while presenting itself primarily as a BTC predictor. Undisclosed external billing integration and credential-dependent behavior increase the risk of unauthorized charging, opaque data flows, and misuse of secrets, especially in a financial context.

Lp3

Medium
Category
MCP Least Privilege
Confidence
80% confidence
Finding
The skill declares access to an environment variable and appears to require networked behavior, but it does not declare any explicit tool scope such as permissions or allowed-tools. This creates a transparency and least-privilege problem: users and platforms cannot reliably assess what capabilities the skill may exercise, especially when it also involves billing-related behavior.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The skill promotes high-frequency, fully automated trading-style usage and advertises strong performance claims without any warning about financial loss, model error, or unattended execution risks. In a financial context, this omission can encourage unsafe reliance on speculative outputs and lead users to make repeated or automated trading decisions without understanding the downside.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
This JavaScript file contains natural-language comments and output strings entirely in Chinese, including values returned in the `signals` objects such as '超卖 → 看涨' and '放量上涨 → 看涨'. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified, which is not present here.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The code hard-codes the zh-CN locale in time formatting, and the skill's help/output strings are entirely in Chinese. This imposes a specific language/locale on all users without any opt-in or indication that the skill is intended only for a Chinese-speaking or region-specific context.

Description-Behavior Mismatch

Medium
Confidence
91% confidence
Finding
The advertised function is directional BTC prediction, but the output goes further by providing concrete trading instructions such as BUY YES/BUY NO along with stop-loss and take-profit levels. This increases user reliance and potential harm, because the skill shifts from informational analysis into actionable financial advice without corresponding disclosure, safeguards, or suitability checks.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The skill is presented as a BTC short-term prediction tool, but it also automatically initiates billing and a recharge flow before delivering the core functionality. This creates a deceptive capability mismatch: users or calling agents may invoke what appears to be an analysis skill without realizing it performs payment operations, increasing the risk of unauthorized charges or unintended financial interaction.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
This code performs a network POST to a billing endpoint containing the user's identifier, skill identifier, and charge amount, but there is no confirmation prompt, user-facing log, or explanatory comment warning that a billable remote request will be made. Because this operation affects user billing and transmits user-related data, the lack of disclosure meets the missing-warning criterion for code files.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The function sends a user's identifier and requested payment amount to a remote billing API, yet the code includes no confirmation prompt, print/log disclosure, or descriptive comment warning the user about this external transmission. Since the operation has privacy and billing implications, it should be disclosed.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
The manifest description and all user-facing documentation are presented only in Chinese, with no indication that users can choose another language or locale. Under the policy, forcing a specific language without opt-in is a natural-language policy violation unless clearly justified.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
The description is written only in Chinese ("BTC 15分钟短线预测 - 技术指标分析"), which can impose a language-specific experience without any indication that users may choose another language. The file does not document that this skill is region-specific or offer any opt-in for locale/language selection.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
The file's natural-language comments are written entirely in Chinese, including the capability descriptions and parameter documentation. Under the stated policy, forcing a specific language without user opt-in or a documented region-specific justification is a locale/language policy issue.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
Natural-language strings and comments such as '收费接口', '扣费', and '开发模式:跳过扣费' indicate a Chinese-language experience without any opt-in or explanation that the skill is intentionally locale-specific. Under the policy, forcing a specific language without user choice is a natural-language policy violation.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/skillpay.js:7