Back to skill

Security audit

A Stock Paper Trade

Security checks for vulnerabilities and agentic risk

Overview

This is a local A-share paper-trading skill with disclosed local portfolio storage and market-data lookups, but users should treat its simulated account data as easy to reset or corrupt.

Install only if you want a Chinese-language local paper-trading helper for A-shares. Confirm before any buy, sell, or reset command, do not rely on it for real financial decisions, and be aware that quote integrity and input validation are weaker than a production trading tool.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/trader.py:59
Finding

Market Quotes Retrieved Over Unencrypted HTTP

Content
View full analysis
dict: """获取实时行情,使用新浪HTTP接口(直连稳定)""" import requests code = _clean_code(symbol) sc = _sina_code(code) url = f"http://hq.sinajs.cn/list={sc}" try: r = requests.get(url, headers={"Referer": "https://finance.sina.com.cn"}, timeout=10) ``` The batch quote implementation has the same weakness: ```python def _get_realtime_quotes_batch(symbols: list) -> list: """批量获取行情""" import requests codes = [_clean_code(s) for s in symbols] scodes = ",".join(_sina_code(c) for c in codes) url = f"http://hq.sinajs.cn/list={scodes}" try: r = requests.get(url, headers={"Referer": "https://finance.sina.com.cn"}, timeout=10) ``` ### Technical Analysis The application retrieves market quotes through plain HTTP. HTTP does not authenticate the remote server or protect response integrity. An attacker capable of intercepting or modifying network traffic can alter stock names, current prices, opening prices, closing prices, and other quote fields before the application processes them. The `Referer` header uses an HTTPS URL, but this does not secure the HTTP request or provide server authentication. Retrieved prices flow directly into market-price buy and sell calculations and can subsequently be persisted in the local portfolio. ### Attack Path 1. A user invokes a quote, buy, sell, positions, or balance operation that retrieves a real-time quote. 2. The application sends an HTTP request to `hq.sinajs.cn`. 3. An attacker controlling the local network, gateway, DNS path, or another interception point modifies the HTTP response. 4. The attacker substitutes a manipulated but syntactically valid price or stock name. 5. The ap ...[truncated 879 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/trader.py:225
Finding

Negative and Non-Finite Trade Prices Can Corrupt Portfolio State

Content
View full analysis
pf["cash"]: print(json.dumps({"error": f"资金不足,需要 {total:,.2f} 元,可用 {pf['cash']:,.2f} 元"}, ensure_ascii=False)) return if not isinstance(qty, int) or qty <= 0: print(json.dumps({"error": "数量必须是正整数(手数,1手=100股)"}, ensure_ascii=False)) return ``` The sell path also accepts an unchecked user-supplied price: ```python price = args.price or q["price"] amount = price * qty fee = max(amount * 0.0003, 5) stamp_tax = amount * 0.001 # 印花税千一(卖出) total_fee = fee + stamp_tax received = amount - total_fee ``` ### Technical Analysis The `--price` argument is parsed as a Python `float`, but the code does not require the value to be finite and greater than zero. Consequently, negative values and special floating-point values such as `NaN` can enter transaction calculations. In the buy path, a negative price produces a negative transaction amount. The commission remains at its minimum value, so the total can remain negative. The insufficient-funds test only rejects totals greater than available cash; it therefore permits a negative total. The later operation: ```python pf["cash"] -= total ``` increases cash when `total` is negative. The transaction and negative cost price are then persisted. Python's float parser also accepts values such as `nan`. Comparisons involving `NaN` do not behave as normal ordered comparisons, and Python's default JSON encoder can write non-standard `NaN` tokens. Such values can propagate through cash, cost b ...[truncated 1714 chars]
Remediation
View remediation
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill invokes a local Python script that reads/writes a portfolio file and fetches live market data over the network, yet the manifest does not declare any explicit tool scope or allowed-tools boundary. This makes the skill's effective capabilities broader and less auditable, increasing the chance that an agent can perform filesystem and network actions without clear consent or policy gating.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The trigger language is very broad and matches common finance terms such as buying, selling, holdings, profit/loss, quotes, ranking, and market discussion. In an agent environment, this can cause the skill to activate for loosely related financial conversations and initiate local trading-script workflows or network-backed market lookups when the user may not have intended to use this specific skill.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The reset path recreates the portfolio file immediately when --reset is supplied, overwriting prior simulated trading history and holdings with no interactive confirmation, backup, or second-step acknowledgement. In this skill’s context the impact is limited to local simulated data integrity, but it can still cause irreversible loss of user state if triggered accidentally or by a higher-level agent misunderstanding the user’s intent.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The natural-language content of the skill is entirely Chinese, including the activation description and usage instructions, and there is no indication that users can choose another language. Under the stated policy, forcing a specific language without opt-in can be a language/locale policy violation unless the restriction is clearly documented and justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The top-level natural-language description and command help text are Chinese-only, which effectively fixes the skill's language without any user opt-in. The file does not state that the tool is intentionally limited to Chinese users or A-share specialists as a documented locale policy exception.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.