Back to skill

Security audit

NiuYao Stock Picker

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a coherent stock-ranking tool, but its documented unattended daily push behavior is under-scoped and the shipped script has reliability and disclosure problems users should review before installing.

Review this skill before installing if you do not want unattended financial reports or notifications. Confirm any daily push destination and disable controls, install dependencies in an isolated environment with pinned versions, and treat the generated rankings as informational rather than 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)

T08 · Insecure Dependencies

Warning
Location
README.md:136
Finding
Unpinned Third-Party Dependencies Create a Supply-Chain Risk<![CDATA[ ## Vulnerability Details **File Location**: `README.md`, lines 136-140 **Vulnerability Type**: Unpinned third-party package installation **Risk Level**: Medium ### Vulnerable Code ```markdown Installation dependencies: ```bash pip install akshare pandas ``` ``` ### Technical Analysis The documented installation command retrieves the latest available versions of `akshare`, `pandas`, and their transitive dependencies without version constraints or integrity hashes. Consequently, installations are not reproducible, and the code installed in the future may differ from the code reviewed during this audit. No evidence indicates that the currently named packages are malicious. The security issue is that the installation process implicitly trusts mutable package releases and their dependency trees. A compromised package publisher account, malicious dependency release, unsafe package-index configuration, or future dependency compromise could introduce arbitrary code into the installation or runtime environment. ### Attack Path 1. An attacker compromises a listed package, one of its transitive dependencies, or the package publisher's distribution account. 2. The attacker publishes a malicious version to the package index used by `pip`. 3. A user follows the documented `pip install akshare pandas` command after the malicious release becomes available. 4. `pip` resolves and installs the compromised release because no reviewed versions or hashes are enforced. 5. Malicious package code executes during installation or when the stock-ranking script imports the dependency. 6. The payload receives the permissions of the user running `pip` or the script. This path depends on a third-party supply-chain compromise; the audited repository does not itself contain such a payload. ### Impact Assessment A successfully compromised dependency could execute arbitrary code with the privileges of the installing or invoking user. Depending on that user's permissions, the ...[truncated 462 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Define reviewed, exact dependency versions in a requirements file: ```text akshare==REVIEWED_VERSION pandas==REVIEWED_VERSION ``` 2. Generate and verify cryptographic hashes for all direct and transitive dependencies, then install with: ```bash python -m pip install --require-hashes -r requirements.txt ``` 3. Use a lock-file workflow that records the complete transitive dependency graph. 4. Install packages only from an explicitly configured trusted package index. 5. Run dependency vulnerability and provenance checks in CI before publishing the Skill. 6. Periodically update pinned versions through a controlled review and testing process. 7. Recommend installation in an isolated virtual environment under a nonprivileged user. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/niu_yao_v1.py:115
Finding
Unbounded External-Data Retry Loop Can Hang and Continuously Issue Requests<![CDATA[ ## Vulnerability Details **File Location**: `scripts/niu_yao_v1.py`, lines 115-132 **Vulnerability Type**: Unbounded retry loop and suppressed external-service errors **Risk Level**: Medium ### Vulnerable Code ```python def get_10d_limit_up_count(code, end_date_str): """近10个交易日涨停次数(准确值)""" end = datetime.strptime(end_date_str, '%Y%m%d') count = 0 checked = 0 current = end while checked < 10: date_str = current.strftime('%Y%m%d') try: df = ak.stock_zt_pool_em(date=date_str) if len(df) > 0: checked += 1 if len(df[df['代码'] == code]) > 0: count += 1 except: pass current -= timedelta(days=1) return count ``` ### Technical Analysis The loop terminates only after ten calls return nonempty datasets. The `checked` counter does not advance when the upstream service returns an empty dataset or raises an exception. All exceptions are silently discarded by the bare `except` block. There is no maximum-attempt counter, earliest permissible date, backoff policy, or explicit failure condition. Therefore, persistent upstream failures, throttling, malformed responses, or empty responses can cause the function to iterate indefinitely. Because the function is called for every candidate stock, the issue can prevent the entire scoring operation from completing and may repeatedly contact the external data provider. The repository does not show that an attacker controls the upstream service. Exploitation requires an upstream failure condition or influence over the network responses consumed through `akshare`. ### Attack Path 1. The user invokes the scoring script. 2. The script calls `get_10d_limit_up_count` for a candidate stock. 3. The upstream market-data request persistently raises exceptions or returns empty data. This may result from an outage, throttling, incompatible API output, network interference, or ...[truncated 938 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Add a strict maximum number of date checks or request attempts. 2. Stop searching after a defined historical range. 3. Apply explicit request timeouts through the underlying client where supported. 4. Use bounded exponential backoff for transient failures. 5. Catch specific exception types rather than using a bare `except`. 6. Log sufficient failure context and return a controlled error when the required data cannot be obtained. 7. Consider caching each trading day's limit-up pool so it is fetched once rather than once per candidate. A bounded implementation could follow this pattern: ```python def get_10d_limit_up_count(code, end_date_str, max_attempts=30): current = datetime.strptime(end_date_str, "%Y%m%d") count = 0 checked = 0 attempts = 0 while checked < 10 and attempts < max_attempts: attempts += 1 date_str = current.strftime("%Y%m%d") try: df = ak.stock_zt_pool_em(date=date_str) except Exception as exc: print(f"Failed to obtain limit-up data for {date_str}: {exc}") current -= timedelta(days=1) continue if df is not None and not df.empty: checked += 1 if not df[df["代码"] == code].empty: count += 1 current -= timedelta(days=1) if checked < 10: raise RuntimeError( f"Only {checked} valid trading days were obtained " f"after {attempts} attempts" ) return count ``` ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (7)

Vague Triggers

Medium
Confidence
94% confidence
Finding
The dialogue trigger phrase '基于最新的股票数据抓牛股复盘一下' is broad and underspecified, making it likely to activate in loosely related finance conversations without clear user intent to invoke this specific skill. In an agent ecosystem, overly permissive triggers can cause unintended tool execution, unexpected data access, or unrequested investment-style analysis, which is especially sensitive in a financial decision-support context.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill documents execution of a local Python script that writes output reports, but the manifest declares no explicit tool scope or permissions. That mismatch weakens least-privilege controls and can allow the skill to perform filesystem writes without clear user or platform visibility into what paths it is expected to modify.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The activation text is broad enough to trigger on ordinary stock discussion, including general analysis or model-building conversations. Over-broad routing can cause the agent to invoke this skill unexpectedly, leading to unrequested trading-oriented automation or execution of associated scripts in contexts where the user only wanted discussion.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The skill advertises an automatic daily run and push behavior but does not describe consent, destination, data handling, failure modes, or how users can disable it. Any unattended push mechanism can create user-impacting automation, including unwanted notifications, data transmission to external channels, or repeated execution without explicit approval.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The module docstring and printed/formatted descriptions repeatedly state the scoring model is composed of six dimensions totaling 100 points. However, the scoring logic adds an undocumented extra 5 points for stocks that hit limit-up on the target day, so actual scores can exceed the documented model and no longer match the claimed weighting.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
This Python file performs a filesystem write by creating a reports directory and saving output to a fixed path under /root/.openclaw/workspace/reports. Although it prints a message after saving, there is no user-facing warning beforehand and the top-level usage docstring does not disclose that running the script will create files on disk.

Description-Behavior Mismatch

Low
Confidence
84% confidence
Finding
The manifest describes screening A股 short-term momentum candidates and daily scoring/push use cases, but this file also persists results locally under /root/.openclaw/workspace/reports. While report generation is adjacent to the purpose, durable file writing is additional behavior not stated in the manifest description itself.

Static analysis

No suspicious patterns detected.