Back to skill

Security audit

Stock Monitor Skill 0.1.0

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed Chinese-market stock alerting and advisory skill with expected background monitoring and market-data calls, but users should treat its financial output as informational only.

Before installing, review and edit the hardcoded watchlist and cost values, understand that ./control.sh start leaves a background monitor running until stopped, and treat generated suggestions as informational rather than investment advice. Prefer HTTPS-only data sources and escaped notification text if you plan to rely on the analysis output.

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/analyser.py:117
Finding
Financial market data retrieved over unencrypted HTTP## Vulnerability Details **File Location**: `scripts/analyser.py`, lines 117-142 **Vulnerability Type**: Plaintext HTTP transport for externally sourced financial data **Risk Level**: Medium ### Vulnerable Code ```python def fetch_dragon_tiger(self, date: str = None) -> List[Dict]: """获取龙虎榜数据""" if not date: date = datetime.now().strftime("%Y%m%d") url = f"http://datacenter-web.eastmoney.com/api/data/v1/get" params = { "sortColumns": "NET_BUY_AMT", "sortTypes": "-1", "pageSize": "50", "pageNumber": "1", "reportName": "RPT_DMSK_TS", "columns": "ALL", "filter": f"(TRADE_DATE='{date}')" } try: resp = self.session.get(url, params=params, timeout=10) data = resp.json() return data.get("result", {}).get("data", []) except: return [] ``` ### Technical Analysis The `fetch_dragon_tiger` method retrieves financial ranking data through plaintext HTTP. HTTP provides neither server authentication nor transport integrity. A network-positioned attacker can therefore intercept the request and modify the response before it reaches the application. The method immediately parses the response as JSON and returns the embedded records without checking the final URL, validating a cryptographic signature, verifying the response schema, or applying reasonable value constraints. Consequently, a forged but syntactically valid JSON response would be treated as legitimate financial data. This method was not found in the normal monitoring loop, which reduces immediate exposure. However, it remains an exposed part of the analysis engine and could be used directly or integrated into the monitoring workflow later. ### Attack Path 1. A user or application component invokes `fetch_dragon_tiger`. 2. The Skill sends an unencrypted HTTP request to the external financial-data endpoint. 3. A ...[truncated 927 chars]
Remediation
## Remediation Suggestions 1. Replace the HTTP endpoint with its verified HTTPS equivalent: ```python url = "https://datacenter-web.eastmoney.com/api/data/v1/get" ``` 2. Preserve TLS certificate verification and do not use `verify=False`. 3. Reject redirects that downgrade the connection from HTTPS to HTTP. 4. Call `resp.raise_for_status()` before parsing the response. 5. Verify that the response content type is JSON. 6. Validate the response against an explicit schema, including expected field names, types, date formats, and numerical ranges. 7. Log transport and validation failures without silently treating malformed responses as valid empty datasets. 8. If the provider does not support HTTPS, replace it with a trusted provider that offers authenticated transport.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/analyser.py:182
Finding
External news titles embedded into HTML-formatted notifications without escaping## Vulnerability Details **File Location**: `scripts/analyser.py`, lines 182-185 **Vulnerability Type**: HTML or notification-markup injection **Risk Level**: Low ### Vulnerable Code ```python # 添加最新新闻标题 if news_list: report += "\n<b>最新动态:</b>\n" for n in news_list[:2]: report += f"• {n.get('title', '无标题')[:30]}...\n" ``` ### Technical Analysis News titles originate from an external financial-data API and are inserted directly into a report that deliberately uses HTML formatting. The title is truncated, but it is not escaped or sanitized before being concatenated into the report. If the downstream notification client interprets HTML, a title containing supported markup may alter message formatting, create a deceptive link, hide surrounding content, or impersonate a trusted report section. Truncation to 30 characters limits payload size but does not reliably prevent injection because short markup payloads can still be meaningful. The vulnerability depends on an attacker being able to influence the upstream news title or compromise the upstream response. Its practical effect also depends on the HTML tags and attributes accepted by the downstream message renderer. ### Attack Path 1. An attacker publishes or otherwise causes a crafted title to appear in the external news feed, or compromises the upstream response. 2. `fetch_eastmoney_news` retrieves the attacker-controlled title. 3. `generate_insight` passes the title through `n.get('title', '无标题')[:30]` without HTML escaping. 4. The generated report is appended to an HTML-formatted alert message. 5. A downstream notification platform interprets accepted markup in the title. 6. The rendered alert may contain attacker-controlled formatting, a deceptive link, or content that appears to be part of the trusted analysis. ### Impact Assessment This issue does not directly provide local code execution, filesystem access, elevated privileges, or crede ...[truncated 391 chars]
Remediation
## Remediation Suggestions 1. Escape every externally sourced value before inserting it into an HTML-formatted message: ```python import html if news_list: report += "\n<b>Latest updates:</b>\n" for item in news_list[:2]: safe_title = html.escape(str(item.get("title", "Untitled"))[:30]) report += f"• {safe_title}...\n" ``` 2. Apply the same escaping to external stock names, API-provided labels, URLs, and other fields used in formatted messages. 3. Keep trusted formatting templates separate from untrusted data. 4. Prefer a notification API that accepts structured text and performs automatic escaping. 5. If selected markup must be accepted, sanitize it with a strict allowlist rather than attempting to remove dangerous strings manually. 6. Add tests containing angle brackets, entities, malformed tags, links, and nested formatting to confirm that external content is rendered only as text.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • 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 (20)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The documented behavior materially differs from the analyzed implementation summary: the skill claims a rules-based alerting system, while code reportedly performs broader network scraping, sentiment analysis, capital-flow collection, and investment-advice generation. This kind of description-behavior mismatch is dangerous because users may grant trust and run the skill expecting limited technical alerts, while the actual code accesses external data and produces higher-risk advisory output outside the declared scope.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The documented behavior materially differs from the analyzed implementation summary: the skill claims a rules-based alerting system, while code reportedly performs broader network scraping, sentiment analysis, capital-flow collection, and investment-advice generation. This kind of description-behavior mismatch is dangerous because users may grant trust and run the skill expecting limited technical alerts, while the actual code accesses external data and produces higher-risk advisory output outside the declared scope.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The documented behavior materially differs from the analyzed implementation summary: the skill claims a rules-based alerting system, while code reportedly performs broader network scraping, sentiment analysis, capital-flow collection, and investment-advice generation. This kind of description-behavior mismatch is dangerous because users may grant trust and run the skill expecting limited technical alerts, while the actual code accesses external data and produces higher-risk advisory output outside the declared scope.

Lp3

Medium
Category
MCP Least Privilege
Confidence
81% confidence
Finding
The skill advertises operation that plausibly requires external market/news access, yet the manifest shown in SKILL.md does not declare any explicit tool scope or permissions boundary. Missing capability declarations weaken reviewability and can let a user or platform misunderstand what external access the skill needs, which is especially risky for a background monitoring service that may continuously fetch remote data.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The description states the skill is tailored to Chinese investor habits, and the document title and content are fully presented in Chinese. Under the policy rule, forcing a specific language or locale is a violation unless the skill offers a language/locale choice or clearly documents a justified regional constraint; this file does not provide such opt-in or limitation.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The manifest describes a stock monitoring and alerting system centered on seven technical alert rules such as cost percentage, moving-average crosses, RSI, volume anomalies, gaps, and dynamic take-profit. This file instead adds broader discretionary analysis features—news scraping, sentiment analysis, capital-flow queries, 龙虎榜 retrieval, and macro gold-correlation analysis—which materially expand the skill beyond the stated alert-focused scope.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
This Python file contains user-facing docstrings and report text entirely in Chinese, including the skill title and generated analysis content. Under the policy rule, forcing a specific language without user opt-in is a natural-language locale violation when no alternative or opt-in mechanism is provided.

Intent-Code Divergence

Medium
Confidence
86% confidence
Finding
The function is documented as '获取东方财富个股新闻', implying it fetches stock news items. However, it calls Eastmoney's suggest API and iterates 'QuotationCodeTable' data, which appears to be search/quotation suggestion data rather than a dedicated news feed, so the documentation overstates what the function actually does.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The script's user-facing comments and all CLI output are in Chinese, including usage and status messages. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is explicitly documented and justified, which is not present in this file.

Session Persistence

Medium
Category
Rogue Agent
Content
echo "🚀 启动 Stock Monitor 后台进程..."
        mkdir -p "$LOG_DIR"
        nohup python3 "$SCRIPT_DIR/monitor_daemon.py" > "$LOG_DIR/monitor.log" 2>&1 &
        echo $! > "$PID_FILE"
        echo "✅ 已启动 (PID: $!)"
        echo "📋 日志: $LOG_DIR/monitor.log"
Confidence
65% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The module docstring states the tool in Chinese and the rest of the user-facing messages are hard-coded in Chinese, which imposes a language choice on users. The file does not offer any language selection or indicate that the skill is intentionally limited to a Chinese-only audience.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The inline documentation states that yesterday's high/low are saved for gap detection, implying real prior-session extremes are available. In reality, the code approximates them as previous close ±2%, which can materially change gap-detection behavior and directly contradicts the comment's claim.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
This code includes natural-language content in Chinese for the module description and operational messages, but there is no indication that users can opt into another language or that the daemon is intentionally limited to a Chinese-speaking context. That creates a language/locale policy concern under the requirement to avoid forcing a specific language without user choice.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
This Python file contains natural-language instructions and status messaging that force a specific language/locale for users and operators. Under the policy, locale-specific language is only acceptable when the skill offers opt-in or clearly documents a justified regional constraint, which is not present here.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The test suite prepends a hardcoded developer-local path to sys.path, causing Python to import code from a location outside the skill package. This creates an import-hijacking and environment-coupling risk: if that path exists and contains a modified monitor module, tests may execute unintended code or validate the wrong implementation.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The README presents the skill description entirely in Chinese, with no indication that users may choose another language or locale. Under the policy rule for natural-language constraints, this is a language/locale limitation that is not documented as optional or region-specific.

Intent-Code Divergence

Low
Confidence
97% confidence
Finding
The function is documented as fetching individual stock fund-flow data from Sina Finance. In practice, it performs a request but does not parse the response and always returns placeholder values like '数据获取中...', which contradicts the stated behavior of actually retrieving fund-flow data.

Intent-Code Divergence

Low
Confidence
96% confidence
Finding
The function claims to fetch northbound capital flow for Stock Connect. The implementation only makes a request and returns a static placeholder string, so the documented intent of returning actual flow information does not match the current behavior.

Description-Behavior Mismatch

Low
Confidence
90% confidence
Finding
The manifest describes a stock monitoring and alerting system centered on seven technical/position-based warning rules. This file additionally implements a news-fetching capability via an Eastmoney company-survey endpoint, which is not reflected in the manifest description and is not necessary to the documented seven-rule alert engine.

Intent-Code Divergence

Low
Confidence
95% confidence
Finding
The inline comment says the current time is New York time and is being converted to Beijing time, but datetime.now() returns the local system time with no timezone semantics. This is an active contradiction between documentation and implementation, especially in a scheduling test where timezone intent matters.

Static analysis

No suspicious patterns detected.