Back to skill

Security audit

Update Stock Mcp

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly purpose-aligned, but it contains real security and control issues users should review before installing.

Review this before installing. Use it only in an isolated environment, keep the Tushare token out of shared folders and backups, avoid exposing sensitive DuckDB files through this MCP server, and do not start QuantAll unless you intend to run a local HTTP MCP service. Prefer pinned dependencies and treat query inputs as unsafe until the SQL construction is fixed.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/UpdateStock_skill.py:1436
Finding

SQL Injection in MCP Stock Query Tools

Content
View full analysis
= '{start_date}' " if end_date: sql += f"AND trade_date <= '{end_date}' " sql += " ORDER BY trade_date;" with duckdb.connect(DB_path) as conn: df = conn.execute(sql).df() ``` The same vulnerable construction is used by both `get_adj_stock` and `get_stock`. ### Technical Analysis The MCP-controlled values `symbol`, `start_date`, and `end_date` are inserted directly into a DuckDB SQL statement using formatted strings. The Pydantic `Field` declarations only provide descriptions and do not enforce the documented six-digit symbol or date formats. An attacker can supply quotes, SQL operators, comments, or other SQL syntax to change the meaning of the query. For example, a crafted `symbol` could terminate the string literal and add an always-true condition, bypassing the intended stock-symbol filter. More damaging statements may be possible if the installed DuckDB driver accepts multiple statements or if database features accessible to the process permit additional file or database operations. Because the MCP tools may be called from agent-generated arguments, malicious content processed by the agent could indirectly provide the injection payload without requiring direct access to the stdio process. ### Attack Path 1. An attacker supplies malicious content to an agent that can invoke this MCP Skill. 2. The content induces the agent to call `get_stock` or `get_adj_stock` with a quote-breaking value in `symbol`, `start_date`, or `end_date`. 3. The MCP handler concatenates the value into the SQL statement without escaping or parameterization. 4. DuckDB interprets the injected characters as S ...[truncated 785 chars]
Remediation
View remediation
= ?") params.append(start_date) if end_date: clauses.append("trade_date <= ?") params.append(end_date) sql = ( "SELECT * FROM stock WHERE " + " AND ".join(clauses) + " ORDER BY trade_date" ) with duckdb.connect(DB_path) as conn: df = conn.execute(sql, params).df() ``` Additionally: 1. Enforce stock symbols with a full-match expression such as `^\d{6}$`. 2. Parse dates with a strict `YYYY-MM-DD` parser before executing the query. 3. Reject unexpected control characters, quotes, comments, and trailing input. 4. Open the database in read-only mode for query-only MCP tools where supported. 5. Add regression tests containing quote-breaking, comment, union, and stacked-statement payloads. 6. Apply the correction independently to both `get_stock` and `get_adj_stock`. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/UpdateStock_skill.py:1542
Finding

Tushare API Token Stored in a Predictable Plaintext File

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Unpinned Dependencies Installed Without Integrity Verification

Content
View full analysis
=1.26.0 pydantic>=2.0.0 pandas>=2.3.3 numpy>=1.24.0 duckdb>=1.5.2 tushare>=1.4.29 baostock>=0.9.1 ``` The documented installation command uses the requirement file with a third-party package mirror: ```bash scripts/.venv/Scripts/python.exe -m pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple ``` ### Technical Analysis Every dependency uses a lower-bound-only version constraint. Consequently, installation may resolve to future package releases that were not present during the Skill review. No lock file or package hashes bind the installation to known artifacts. The documentation also directs users to a third-party Python package mirror. This does not establish that the mirror is malicious, but it expands the supply-chain trust boundary. If the index, a dependency account, or a future allowed release is compromised, malicious package code could be installed without any change to this Skill repository. Python packages may execute code during build or installation, and all listed packages execute imported code when the MCP server starts. Therefore, dependency compromise can result in code execution with the same privileges as the installing user or MCP process. ### Attack Path 1. A user follows the documented installation command. 2. Pip resolves each `>=` constraint to the newest compatible release available from the configured mirror. 3. A future release, transitive dependency, package account, distribution artifact, or mirror is compromised. 4. Because no exact version or hash is required, pip accepts and installs the changed artifact. 5. Malicious code executes during package installation, import, or subsequent MCP operation with the user's privileges. ...[truncated 512 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (25)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared purpose centers on stock database management, but the skill also starts a local HTTP service, probes a localhost port, dynamically generates a Python launcher script, and persists settings and API credentials to disk. This description-behavior gap is dangerous because operators may approve the skill expecting data management only, while it also performs process execution, network exposure, and local state changes that materially expand the attack surface.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill can spawn a subprocess, create a startup script on disk, and monitor a localhost port to launch another MCP service. In context, this is more dangerous because the advertised purpose is stock-data management, yet the implementation adds local service orchestration that could be leveraged to run unintended code or expose a local endpoint without clear user awareness.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill documentation describes capabilities that include reading and writing local files and invoking local Python processes, but it does not declare any explicit tool scope such as permissions or allowed-tools. That makes the skill harder to audit and increases the chance an agent may invoke filesystem or shell-capable behavior without clear user-visible boundaries, especially because it handles credentials in API_tushare.txt and writes configuration files.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The trigger conditions use broad phrasing such as '等', which creates ambiguous activation boundaries for a skill that can write files, update databases, and start local services. Over-broad triggering increases the risk of accidental invocation in loosely related financial conversations, causing unintended filesystem changes, long-running updates, or service startup without sufficiently specific user intent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The tool reads a Tushare API credential from a local file and then performs network requests without prominently disclosing this secret usage in the tool interface. In an agent context, implicit credential consumption is risky because users may trigger outbound authenticated actions without understanding that locally stored credentials will be used.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This simplified update path also silently reads a local API credential file and performs external fetches. The danger is contextual: a user invoking a stock update tool may not realize they are authorizing network activity with a stored credential, which undermines informed consent and secret-handling transparency.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill manifest describes stock database management, but the code additionally starts and configures a separate QuantAll MCP service. This capability expansion violates least privilege and user expectations, making the skill more dangerous because it can alter the local execution environment beyond the scope needed for stock-data updates.

Content

No source excerpt is available for this finding.

Unbounded Resource Access

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.

Content

Scanner excerpt · scripts/UpdateStock_skill.py (reported line 1638)May include surrounding context.

python
str: 包含服务状态、PID(若新启动)和连接地址的提示信息。
    """
    # 1. 检查端口是否已占用(服务已在运行)
    if _is_port_open("127.0.0.1", 8686, timeout=0.5):
        return (f"QuantAll 服务已在运行,可直接连接 http://127.0.0.1:8686/mcp 。\n"
                "如需重启,请先终止已有进程。")

Unbounded Resource Access

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.

Content

Scanner excerpt · scripts/UpdateStock_skill.py (reported line 1694)May include surrounding context.

python
str: 包含服务状态、PID(若新启动)和连接地址的提示信息。
    """
    # 1. 检查端口是否已占用(服务已在运行)
    if _is_port_open("127.0.0.1", 8686, timeout=0.5):
        return (f"QuantAll 服务已在运行,可直接连接 http://127.0.0.1:8686/mcp 。\n"
                "如需重启,请先终止已有进程。")

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The tool dynamically writes Start_QuantAll.py to disk and launches it as a detached subprocess without a confirmation step. That combination of file-system modification plus background execution is security-sensitive because it changes the local system state in a way users may not expect from a stock-data skill, and it can be abused to persist or proxy execution behavior.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
93% confidence
Finding

This subprocess launch is a real security-relevant issue because the skill exposes a tool that can start a detached local process (Start_QuantAll) from within an ostensibly stock-update skill. Although the command arguments are not directly user-controlled, spawning a long-lived child process and suppressing its I/O materially expands the skill’s capabilities and can be abused for unauthorized local service execution or persistence-like behavior.

Content

Scanner excerpt · scripts/UpdateStock_skill.py (reported line 1670)May include surrounding context.

python
try:
        # 启动子进程(忽略 I/O)
        if sys.platform == "win32":
            process = subprocess.Popen(
                [python_exe, str(target_script)],
                cwd=str(current_dir),
                creationflags=subprocess.CREATE_NEW_PROCESS_GROUP,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
93% confidence
Finding

This is the Unix-like branch of the same detached process-launch behavior and carries the same risk profile. Launching a background process with start_new_session=True and null stdio makes the action stealthier and harder for users to observe or control, which is dangerous in an agent skill that should primarily manage stock data.

Content

Scanner excerpt · scripts/UpdateStock_skill.py (reported line 1679)May include surrounding context.

python
stdin=subprocess.DEVNULL
            )
        else:
            process = subprocess.Popen(
                [python_exe, str(target_script)],
                cwd=str(current_dir),
                stdout=subprocess.DEVNULL,

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

The dependency specification uses a lower-bound range (mcp>=1.26.0) rather than an exact pin, which makes builds non-reproducible and may allow installation of a later vulnerable or incompatible release. In a skill that exposes MCP/stdIO service functionality, drifting to an unsafe SDK version can directly affect the security posture of the service runtime.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
mcp>=1.26.0
pydantic>=2.0.0
pandas>=2.3.3
numpy>=1.24.0

Unverifiable Dependency: mcp has 12 known advisory(ies) (CVE-2025-53366 (MCP Python SDK vulnerability in the FastMCP Server causes validation error, lead); CVE-2025-66416 (Model Context Protocol (MCP) Python SDK does not enable DNS rebinding protection); CVE-2026-52870 (MCP Python SDK: Experimental task handlers allow any client to access and cancel) +9 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The manifest references mcp without an exact version while the package family has known advisories, so it is impossible to determine from this file whether the deployed SDK is affected. Because this skill explicitly runs an MCP service over stdio, any vulnerable mcp version is more consequential here than in a non-MCP project.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

Using pydantic>=2.0.0 leaves the installed version uncontrolled, so environments may resolve to different releases with different bug and security characteristics. While not an exploit by itself, this weakens supply-chain assurance and makes it hard to verify whether known issues are fixed.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
mcp>=1.26.0
pydantic>=2.0.0
pandas>=2.3.3
numpy>=1.24.0
duckdb>=1.5.2

Unverifiable Dependency: pydantic has 4 known advisory(ies) (CVE-2021-29510 (Use of "infinity" as an input to datetime and date fields causes infinite loop i); CVE-2024-3772 (Pydantic regular expression denial of service); CVE-2021-29510 (Pydantic is a data validation and settings management using Python type hinting.) +1 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
88% confidence
Finding

pydantic has known advisories, and the unpinned requirement prevents verification that the installed version contains the relevant fixes. This primarily creates uncertainty and patch-management weakness rather than proving active exposure from this file alone.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

pandas>=2.3.3 is unpinned, so dependency resolution may pull newer releases without review. This creates avoidable supply-chain and reproducibility risk, especially in a data-processing skill that likely handles external market data inputs.

Content

Scanner excerpt · requirements.txt (reported line 3)May include surrounding context.

text
mcp>=1.26.0
pydantic>=2.0.0
pandas>=2.3.3
numpy>=1.24.0
duckdb>=1.5.2
tushare>=1.4.29

Unverifiable Dependency: pandas has 1 known advisory(ies) (CVE-2020-13091 (** DISPUTED ** pandas through 1.0.3 can unserialize and execute commands from an)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
82% confidence
Finding

The file does not pin pandas, so it is not possible to verify whether a safe release is installed despite known advisory history. In this context the risk is limited because the requirement shown does not itself demonstrate unsafe pandas usage, but version ambiguity remains a supply-chain weakness.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

numpy>=1.24.0 permits unreviewed future versions to be installed, reducing build determinism and making vulnerability exposure unclear. For a data-heavy service, core numerical libraries should be tightly controlled because they are broadly trusted and widely used throughout the execution path.

Content

Scanner excerpt · requirements.txt (reported line 4)May include surrounding context.

text
mcp>=1.26.0
pydantic>=2.0.0
pandas>=2.3.3
numpy>=1.24.0
duckdb>=1.5.2
tushare>=1.4.29
baostock>=0.9.1

Unverifiable Dependency: numpy has 16 known advisory(ies) (CVE-2014-1859 (Numpy arbitrary file write via symlink attack); CVE-2021-41495 (NumPy NULL Pointer Dereference); CVE-2021-33430 (NumPy Buffer Overflow (Disputed)) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
86% confidence
Finding

numpy has known advisories, and the absence of an exact version prevents determining whether the runtime package is affected. This is a dependency hygiene issue that can widen attack surface indirectly when foundational libraries are allowed to drift.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

duckdb>=1.5.2 does not guarantee a specific release, so deployments may pick different versions with different security properties. Given this skill manages a local DuckDB database and may process externally sourced stock data, unpinned database components increase operational and security risk.

Content

Scanner excerpt · requirements.txt (reported line 5)May include surrounding context.

text
pydantic>=2.0.0
pandas>=2.3.3
numpy>=1.24.0
duckdb>=1.5.2
tushare>=1.4.29
baostock>=0.9.1

Unverifiable Dependency: duckdb has 4 known advisory(ies) (CVE-2024-41672 (sniff_csv provides filesystem access even when enable_external_access is disable); CVE-2024-41672 (DuckDB is a SQL database management system. In versions 1.0.0 and prior, content); CVE-2024-22682 (DuckDB <=0.9.2 and DuckDB extension-template <=0.9.2 are vulnerable to malicious) +1 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
94% confidence
Finding

duckdb has known advisory history, and the unpinned dependency means the actual installed version could be vulnerable without any visibility from this manifest. Since the skill's purpose includes creating and updating a DuckDB-based stock database, a vulnerable DuckDB release would be directly in the data-processing path and therefore more dangerous in this context.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

tushare>=1.4.29 allows version drift for an external market-data dependency. Although this is not evidence of a direct exploit, it creates supply-chain uncertainty and can introduce vulnerable or malicious upstream changes into the skill without explicit review.

Content

Scanner excerpt · requirements.txt (reported line 6)May include surrounding context.

text
pandas>=2.3.3
numpy>=1.24.0
duckdb>=1.5.2
tushare>=1.4.29
baostock>=0.9.1

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

baostock>=0.9.1 is unpinned, so installations are not reproducible and may resolve to different package contents over time. For software that ingests remote financial data, this increases supply-chain exposure and complicates incident response and auditability.

Content

Scanner excerpt · requirements.txt (reported line 7)May include surrounding context.

text
numpy>=1.24.0
duckdb>=1.5.2
tushare>=1.4.29
baostock>=0.9.1

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
99% confidence
Finding

The ping tool’s docstring says 检查是否能连接, implying an actual connectivity or readiness test. In reality, the function unconditionally returns "Pong" and does not verify any connection state, making the inline documentation actively misleading about what the tool does.

Content

No source excerpt is available for this finding.