Back to skill

Security audit

eastmoney skills

Security checks for vulnerabilities and agentic risk

Overview

This skill fits a simulated stock-trading purpose, but it needs Review because it can submit or cancel simulated trades and send the API key to a configurable URL without enough safeguards.

Install only if you trust the 妙想 API key and environment configuration. Keep MX_API_URL set to the documented HTTPS service, use a limited or revocable API key if possible, and do not let the agent run buy, sell, or cancel requests unless you have clearly confirmed the exact action. Be aware that account and order responses are saved locally as raw JSON in the OpenClaw workspace.

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/mx_stock_simulator.py:50
Finding
Configurable API destination can expose the API key and account requests<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mx_stock_simulator.py`, lines 13-14 and 50-58 **Vulnerability Type**: Unvalidated credential-bearing request destination **Risk Level**: High ### Vulnerable Code ```python MX_APIKEY = os.environ.get('MX_APIKEY') MX_API_URL = os.environ.get('MX_API_URL', 'https://mkapi2.dfcfs.com/finskillshub') ``` ```python def make_request(endpoint, payload): """发送POST请求到API""" url = f"{MX_API_URL}{endpoint}" headers = { 'apikey': MX_APIKEY, 'Content-Type': 'application/json' } try: response = requests.post(url, headers=headers, json=payload, timeout=30) ``` ### Technical Analysis `MX_API_URL` is accepted directly from the environment without validating its scheme, hostname, port, or embedded credentials. Every request then transmits `MX_APIKEY` in an HTTP header to the configured destination. Consequently, an attacker who can influence the process environment or deployment configuration can replace the legitimate API endpoint with an attacker-controlled URL. The code does not require HTTPS and does not restrict the destination to the documented `mkapi2.dfcfs.com` host. In addition, `requests` follows redirects by default, and the code does not explicitly validate the final destination. ### Attack Path 1. The attacker obtains control over the Skill's environment configuration, launch script, container configuration, or another source that sets `MX_API_URL`. 2. The attacker sets `MX_API_URL` to an HTTP or HTTPS server under their control. 3. A user invokes a balance, holdings, order, cancellation, buy, or sell operation. 4. `make_request()` constructs the URL from the attacker-controlled base value. 5. The program sends the `apikey` header and operation payload to the attacker's server. 6. The attacker captures the API key and request data and may use the credential against the legitimate service, su ...[truncated 547 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not allow arbitrary origins for credential-bearing requests. - Parse the configured URL with `urllib.parse.urlparse` and require: - The `https` scheme. - An explicitly approved hostname such as `mkapi2.dfcfs.com`. - An approved port. - No username or password embedded in the URL. - Prefer a fixed service origin unless alternate endpoints are operationally required. - Disable automatic redirects with `allow_redirects=False`, or validate every redirect target before following it. - Never forward the API key when a redirect changes the origin. - Fail closed when URL validation fails and avoid including the credential in error messages. - Consider using a narrowly scoped, short-lived API credential where supported. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/mx_stock_simulator.py:30
Finding
Sensitive account and transaction responses are stored without explicit access restrictions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mx_stock_simulator.py`, lines 17-18 and 30-48 **Vulnerability Type**: Insecure persistent storage of sensitive data **Risk Level**: Medium ### Vulnerable Code ```python OUTPUT_DIR = '/root/.openclaw/workspace/mx_data/output' PREFIX = 'mx_stock_simulator_' ``` ```python def save_result(query, text, data): """保存结果到文件""" ensure_output_dir() safe_query = query.replace(' ', '_')[:50] # 保存文本结果 txt_file = os.path.join(OUTPUT_DIR, f"{PREFIX}{safe_query}.txt") with open(txt_file, 'w', encoding='utf-8') as f: f.write(text) # 保存原始JSON json_file = os.path.join(OUTPUT_DIR, f"{PREFIX}{safe_query}.json") with open(json_file, 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=2) return txt_file, json_file ``` ### Technical Analysis Every successful operation is saved as both formatted text and raw JSON. These responses can contain balances, holdings, order history, stock positions, order identifiers, account identifiers, and transaction results. The program does not explicitly set directory mode `0700` or file mode `0600`. Effective permissions therefore depend on the process umask and any pre-existing workspace-directory permissions. Under permissive runtime settings, other local users or processes may be able to read the generated records. The storage is automatic rather than opt-in, and no retention, deletion, encryption, or data-redaction mechanism is provided. Files can therefore remain available after the operation that produced them has completed. ### Attack Path 1. A user invokes an account query or simulated-trading operation. 2. `save_result()` writes the formatted response and complete raw API response to the fixed output directory. 3. The files inherit permissions derived from the ambient umask, or are created inside an existing dire ...[truncated 870 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Make response persistence opt-in rather than automatic. - Create the output directory with mode `0700` and verify the permissions of an existing directory before use. - Create output files atomically with mode `0600`, for example by using `os.open()` with explicit flags and permissions. - Refuse to write through symbolic links and verify that the resolved destination remains inside the approved output directory. - Redact account IDs, order IDs, and other unnecessary sensitive fields before persistence. - Avoid storing raw API responses unless they are explicitly required. - Introduce a configurable retention period and securely delete expired records. - Where long-term storage is necessary, encrypt records with an appropriately protected key. ]]>

T08 · Insecure Dependencies

Note
Location
scripts/requirements.txt:1
Finding
Third-party dependency is installed without a version or integrity constraint<![CDATA[ ## Vulnerability Details **File Location**: `scripts/requirements.txt`, line 1 **Vulnerability Type**: Unpinned third-party dependency **Risk Level**: Low ### Vulnerable Code ```text requests ``` ### Technical Analysis The `requests` dependency has no exact version constraint or package hash. Each installation can therefore resolve to a different release based on the package index state at installation time. This makes builds non-reproducible and prevents the project from guaranteeing that the installed artifact is the version that was reviewed. Although the dependency name is legitimate and the project does not specify an obviously unsafe package source, an unconstrained installation increases exposure to a compromised future release, package-index compromise, or an incompatible release. ### Attack Path 1. The Skill environment installs dependencies from `requirements.txt`. 2. The package resolver selects whichever `requests` release currently satisfies the unconstrained requirement. 3. If the selected distribution or configured package index is compromised, malicious package code can execute during installation or when the package is imported. 4. Such code runs with the privileges of the installing or Skill-running process and may access the environment, including `MX_APIKEY`. This path depends on a compromised dependency release, artifact, or package source; the audited project does not itself demonstrate that the current `requests` package is malicious. ### Impact Assessment A malicious dependency could execute arbitrary Python code with the privileges of the installation or runtime account. In this deployment, that could expose environment credentials, modify generated files, tamper with API requests, or access other resources available to the process. The immediate likelihood is limited because no malicious package or unsafe custom index was identified in the audited files. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Pin `requests` to a reviewed, supported version using an exact version constraint. - Generate a lock file containing all transitive dependency versions. - Require cryptographic hashes during installation, such as with `pip install --require-hashes`. - Install packages only from an approved HTTPS package index. - Run automated vulnerability and dependency-update monitoring. - Review and test dependency upgrades before updating the lock file. - Perform dependency installation with the minimum necessary operating-system privileges. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (14)

Tainted flow: 'url' from os.environ.get (line 54, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
}
    
    try:
        response = requests.post(url, headers=headers, json=payload, timeout=30)
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
Confidence
95% confidence
Finding
The request destination is built from the MX_API_URL environment variable and used directly in requests.post while sending the apikey header and trading/account payloads. If an attacker can influence the runtime environment, they can redirect sensitive requests to an attacker-controlled host, exfiltrating credentials and financial data and potentially capturing trade instructions.

Missing User Warnings

High
Confidence
97% confidence
Finding
Buy, sell, and cancel operations are executed immediately from parsed natural-language input with no confirmation step, dry-run preview, or secondary approval. In an agent setting, ambiguous phrasing, prompt injection, or accidental invocation can therefore trigger destructive financial actions and mass cancellation of orders.

Lp3

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding
The skill declares capabilities that involve environment access, outbound network requests, and file output, but it does not constrain them with explicit tool scope such as permissions or allowed-tools. In a trading-oriented skill, that omission is dangerous because an agent could access secrets, transmit them to a remote endpoint, and write sensitive account data to disk without clear sandbox limits or user-visible restrictions.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The skill enables buy, sell, and especially one-click cancel operations, but it does not present an explicit warning or confirmation requirement for destructive account actions. In a financial-trading context, even a simulator can cause account state changes, strategy disruption, or unintended mass cancellation if an agent misinterprets a user request.

External Transmission

Medium
Category
Data Exfiltration
Content
- **成功响应**:`{ }`

```bash
curl -X POST "${MX_API_URL}/api/claw/mockTrading/positions" \
  -H "apikey: ${MX_APIKEY}" \
  -H "Content-Type: application/json" \
  -d '{}'
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
- **委托价格说明**:当 `useMarketPrice=false` 时,price参数必填,且需符合市场规则:沪市价格小数位不超过2位,深市价格小数位不超过3位;当 `useMarketPrice=true` 时,price参数会被忽略,系统会自动以行情最新价进行买入。

```bash
curl -X POST "${MX_API_URL}/api/claw/mockTrading/trade" \
  -H "apikey: ${MX_APIKEY}" \
  -H "Content-Type: application/json" \
  -d '{
Confidence
87% confidence
Finding
This request sends trade instructions to an external API and can cause state-changing buy or sell operations. In the absence of stronger guardrails like confirmation, domain allowlisting, and action scoping, an agent could execute unauthorized or mistaken trades using the user's API key.

External Transmission

Medium
Category
Data Exfiltration
Content
- **股票代码格式说明**:仅支持A股,格式为6位数字,例如 `600519`、`000001`,系统会自动识别并补全市场号;另外股票代码在type为order时必传。

```bash
curl -X POST "${MX_API_URL}/api/claw/mockTrading/cancel" \
  -H "apikey: ${MX_APIKEY}" \
  -H "Content-Type: application/json" \
  -d '{
Confidence
91% confidence
Finding
This request can cancel one order or all pending orders through an external API, making it a destructive state-changing action. In a trading workflow, mass cancellation without strong confirmation and scoping is risky because a prompt misunderstanding could disrupt the user's active strategy or erase pending execution opportunities.

External Transmission

Medium
Category
Data Exfiltration
Content
| `fltOrderStatus` | 否   | 0=全部(默认),2=已报,4=已成 等 |

```bash
curl -X POST "${MX_API_URL}/api/claw/mockTrading/orders" \
  -H "apikey: ${MX_APIKEY}" \
  -H "Content-Type: application/json" \
  -d '{
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Natural-Language Policy Violations

Medium
Confidence
84% confidence
Finding
User-facing docstrings, prompts, and output messages are entirely in Chinese, and the skill does not indicate that Chinese is optional or required for a region-specific reason. Under the policy, forcing a specific language without user opt-in is a natural-language policy concern.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The script persistently writes account balances, holdings, orders, and trade results to /root/.openclaw/workspace/mx_data/output without user notice or consent. These files may contain sensitive financial data and, in shared or multi-tenant environments, could be exposed to other processes, backups, or later compromise.

External Transmission

Medium
Category
Data Exfiltration
Content
}
    
    try:
        response = requests.post(url, headers=headers, json=payload, timeout=30)
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The manifest and module docstring state that the skill supports 历史成交查询, which implies querying completed trade history. However, the intent parser maps phrases like '成交记录' and '历史成交' to the 'orders' intent, and the main handler only calls /api/claw/mockTrading/orders, which is presented as 委托查询 rather than a historical fills endpoint. This is a semantic mismatch between the advertised capability and implemented behavior.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests
Confidence
98% confidence
Finding
The dependency file specifies `requests` without a version constraint, which makes builds non-reproducible and can cause deployment of unexpectedly vulnerable or breaking releases. In a stock trading simulator that performs authenticated API operations, dependency drift in a core HTTP client increases the chance of exposure to known or future transport, redirect, credential-handling, or verification issues.

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +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
95% confidence
Finding
Because `requests` is unpinned, it is impossible to verify whether the installed version includes fixes for its many published security advisories. This is especially concerning in a skill that interacts with trading APIs and may handle credentials, account data, and transaction requests, where a vulnerable HTTP library could contribute to credential leakage, TLS/verification issues, or unsafe request handling.

Static analysis

No suspicious patterns detected.