Back to skill

Security audit

stock-unified

Security checks for vulnerabilities and agentic risk

Overview

This is a market-data lookup skill that contacts public finance data providers; it has underdocumented extra finance features, but I found no evidence of credential theft, persistence, destructive behavior, or hidden local data access.

Install this only where outbound queries to public finance providers are acceptable. Expect requested stock symbols, ETF/index/futures symbols, and your network metadata to be sent to services such as Sina, Eastmoney, Tongdaxin/pytdx, Tonghuashun/akshare-backed sources, and Tencent fallback endpoints. Review the script help if you need the complete feature list before use.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (17)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The documented purpose and data-source list do not fully match the broader behavior detected for the skill, including additional markets, analytics, and undeclared external providers. This is dangerous because hidden or undocumented functionality increases the attack surface, bypasses informed consent and review, and may route data to services that operators did not approve.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill advertises commands that invoke Python scripts with network access and shell execution semantics, but it does not declare any tool scope such as allowed-tools or permissions. This weakens least-privilege controls and can cause the agent runtime to grant broader capabilities than users or reviewers expect, especially for a skill that reaches multiple external data sources.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/data_provider.py (reported line 14)May include surrounding context.

python
"""调用 unified_stock.py CLI 并解析 JSON 输出"""
    try:
        cmd = [sys.executable, SCRIPT] + list(args) + ["--json"]
        r = subprocess.run(cmd, capture_output=True, text=True, timeout=15)
        out = r.stdout.strip()
        # 尝试提取首个 { } JSON 块
        m = re.search(r"\{.*\}", out, re.DOTALL)

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

The skill transmits user-requested market query data and runtime metadata to multiple third-party services such as Eastmoney, Sina, Tencent, and potentially akshare-backed providers. In an agent environment, undeclared external transmission can expose user interests, trading research patterns, IP/network metadata, and query contents to outside parties, especially since the skill automatically fails over across several providers.

Content

Scanner excerpt · scripts/unified_stock.py (reported line 34)May include surrounding context.

python
EASTAPI_BASE = "https://datacenter.eastmoney.com/api/data/v1/get"
EAST_HEADERS = {
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
    "Referer": "https://data.eastmoney.com/",
}

SINA_BASE = "https://hq.sinajs.cn"

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest describes the skill as a unified stock data interface for A-share scenarios such as real-time quotes, K-lines, sectors, constituents, and financial data. However, the code adds explicit support for international futures symbols and later U.S. stock indices, which extends beyond the stated A-share stock scope rather than serving as an obvious implementation detail.

Content

No source excerpt is available for this finding.

Tainted flow: 'req' from requests.get (line 379, network input) → urllib.request.urlopen (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/unified_stock.py (reported line 383)May include surrounding context.

python
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
                "Referer": "https://finance.sina.com.cn"
            })
            with urllib.request.urlopen(req, timeout=10) as resp:
                data = resp.read().decode('gbk')
            
            m = re.search(r'"([^"]*)"', data)

Tainted flow: 'req' from requests.get (line 379, network input) → urllib.request.urlopen (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/unified_stock.py (reported line 466)May include surrounding context.

python
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
                "Referer": "https://finance.sina.com.cn"
            })
            with urllib.request.urlopen(req, timeout=10) as resp:
                data = resp.read().decode('gbk')
            
            m = re.search(r'"([^"]*)"', data)

Tainted flow: 'req' from requests.get (line 379, network input) → urllib.request.urlopen (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/unified_stock.py (reported line 678)May include surrounding context.

python
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
                "Referer": "https://finance.sina.com.cn"
            })
            with urllib.request.urlopen(req, timeout=10) as resp:
                data = resp.read().decode('gbk')
            
            m = re.search(r'"([^"]*)"', data)

Tainted flow: 'req' from requests.get (line 379, network input) → urllib.request.urlopen (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/unified_stock.py (reported line 1098)May include surrounding context.

python
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
                "Referer": "https://finance.sina.com.cn"
            })
            with urllib.request.urlopen(req, timeout=10) as resp:
                data = resp.read().decode('gbk')
            
            m = re.search(r'"([^"]*)"', data)

Tainted flow: 'url' from requests.get (line 378, network input) → requests.get (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/unified_stock.py (reported line 1416)May include surrounding context.

python
"fid": "f3", "fs": "m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23",
            "fields": "f104,f105",
        }
        r = requests.get(url, params=params, headers=EAST_HEADERS, timeout=10)
        data = r.json()
        if data.get("data"):
            total = data["data"].get("total", 0)

External Transmission

Medium
Category
Data Exfiltration
Confidence
86% confidence
Finding

This code performs additional outbound requests to Eastmoney for northbound capital-flow analytics, which broadens third-party data sharing beyond the core stock quote use case. In the skill context, the danger is not code injection but silent expansion of external data transmission and dependency footprint, which matters for privacy, compliance, and network governance.

Content

Scanner excerpt · scripts/unified_stock.py (reported line 1457)May include surrounding context.

python
'klt': '101', 'lmt': days + 2,
            'ut': 'b2884a393a59ad64002292a3e90d46a5',
        }
        headers = {'User-Agent': 'Mozilla/5.0', 'Referer': 'https://data.eastmoney.com/hsgt/index.html'}
        
        all_rows = []
        for secid in ['1.0001', '1.0003']:  # 北向沪 + 北向深

Tainted flow: 'url' from requests.get (line 378, network input) → requests.get (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/unified_stock.py (reported line 1462)May include surrounding context.

python
all_rows = []
        for secid in ['1.0001', '1.0003']:  # 北向沪 + 北向深
            params = {**base_params, 'secid': secid}
            r = requests.get(url, params=params, headers=headers, timeout=10)
            m = re.search(r'\((.*)\)', r.text, re.DOTALL)
            if m:
                d = json.loads(m.group(1))

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

This markdown file contains only Chinese-language headings and content, with no indication that users may choose another language or that the skill is intentionally limited to Chinese-speaking or China-market contexts. Under the policy rule for language/locale constraints, forcing a single language without opt-in can be a natural-language policy issue.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The module docstring is written entirely in Chinese and provides no indication that language selection is optional or that the skill is intentionally limited to a Chinese-speaking context. Under the stated policy, forcing a specific language without user opt-in can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The module docstring, usage examples, and CLI help are presented entirely in Chinese, which imposes a specific language on users without any opt-in or alternative locale. The policy only allows such constraints when the skill offers language choice or clearly documents a justified region-specific limitation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest enumerates stock-oriented use cases like stock price queries, sector rankings, constituent stocks, K-lines, and financial data. This file additionally adds ETF historical K-line retrieval and ETF fund-flow analysis as dedicated features, which are adjacent to finance data but still exceed the manifest's stated functional scope.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest states usage for stock quotes, board rankings, constituents, K-lines, financials, and board search. The added market breadth sentiment metrics and northbound fund-flow summaries are broader market analytics capabilities that are not described in the manifest and are not necessary to fulfill the listed stock-query scenarios.

Content

No source excerpt is available for this finding.