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

Content
View full analysis

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
View 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

Content
View full analysis

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
View 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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · scripts/control.sh (reported line 17)May include surrounding context.

sh
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"

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.