Back to skill

Security audit

Stock Summary

Security checks for vulnerabilities and agentic risk

Overview

This stock-analysis skill is not deceptive, but it should be reviewed because it can produce unreliable trading signals and writes charts to a fixed privileged path.

Install only if you are comfortable treating the output as a rough, non-personalized technical summary. Do not rely on its buy/sell/hold signal for financial decisions, especially for Hong Kong tickers or A-share data, until the routing, quote fields, HTTPS/data validation, and chart output path are fixed.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/stock_summary.py:31
Finding
Unencrypted transport permits manipulation of stock data and trading signals<![CDATA[ ## Vulnerability Details **File Location**: `scripts/stock_summary.py`, lines 31-55 **Vulnerability Type**: Plaintext HTTP transport for externally sourced financial data **Risk Level**: Medium ### Vulnerable Code ```python url = f'http://push2.eastmoney.com/api/qt/stock/get?secid=1.{code}&fields=f43,f44,f45,f46,f47,f48,f57,f58,f60,f107,f169,f170' try: r = requests.get(url, timeout=5) d = r.json()['data'] ``` ```python url = f'http://push2his.eastmoney.com/api/qt/stock/kline/get?secid=1.{code}&fields1=f1,f2,f3,f4,f5,f6&fields2=f51,f52,f53,f54,f55,f56,f57&klt=101&fqt=1&end=20500101&lmt=30' try: r = requests.get(url, timeout=5) data = r.json()['data']['klines'] ``` ### Technical Analysis The A-share quote and historical-data functions retrieve financial information over unencrypted HTTP. HTTP provides neither transport confidentiality nor server authenticity and does not protect response integrity. An attacker able to observe or modify network traffic—such as a compromised router, malicious access point, proxy, or network-adjacent adversary—can alter the returned JSON and K-line records. The application trusts these values and uses the historical closing prices to calculate RSI and MACD indicators and to produce buy, sell, or hold recommendations. The requests also do not call `raise_for_status()` or perform robust response-schema and financial-value validation. This makes manipulated or unexpected responses more likely to be accepted or handled ambiguously. ### Attack Path 1. A user invokes the skill with an A-share stock code. 2. The script sends quote and historical-data requests over plaintext HTTP. 3. A network-positioned attacker intercepts one or both requests. 4. The attacker returns modified JSON containing manipulated prices, volume, or historical K-line values. 5. The script parses the response without authenticating its origin or validating the financial values. 6. The manipulated historical prices are passed to the R ...[truncated 647 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the HTTP endpoints with official HTTPS equivalents and retain normal TLS certificate verification. 2. Reject redirects from HTTPS to HTTP. 3. Call `r.raise_for_status()` before parsing each response. 4. Validate the response schema, including the presence and expected types of all required fields. 5. Apply reasonable range and consistency checks to prices, dates, and volume before using them. 6. Fail closed when authentication, parsing, or validation fails instead of generating a recommendation from questionable data. 7. Consider cross-checking high-impact financial values against a second trusted source. 8. Log failures without recording sensitive request metadata unnecessarily. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/stock_summary.py:244
Finding
Predictable chart path enables file clobbering and potential symlink-based writes<![CDATA[ ## Vulnerability Details **File Location**: `scripts/stock_summary.py`, lines 244-245 **Vulnerability Type**: Unsafe fixed output file in a privileged workspace **Risk Level**: Medium ### Vulnerable Code ```python output_path = '/root/.openclaw/workspace/stock_chart.png' plt.savefig(output_path, dpi=150, bbox_inches='tight') ``` ### Technical Analysis The chart is always written to a predictable, absolute path beneath `/root`. Every execution overwrites the same file without checking whether the destination already exists, whether it is a symbolic link, or whether it is a regular file owned by the expected user. If a less-privileged attacker can modify the workspace or pre-create `stock_chart.png`, the attacker may replace the destination with a symbolic link. When the skill subsequently runs with elevated privileges, the chart-writing operation may follow that link and overwrite another file writable by the executing account. Even when symlink exploitation is not possible, concurrent or repeated executions can overwrite one another's output, causing cross-request file clobbering and incorrect chart delivery. ### Attack Path 1. The skill runs under an account that can write to `/root/.openclaw/workspace`. 2. An attacker obtains the ability to create or replace entries in that workspace, such as through shared-volume permissions or another process using the same directory. 3. The attacker creates `stock_chart.png` as a symbolic link to a chosen file writable by the skill's account. 4. A user invokes the stock-summary skill. 5. `plt.savefig()` opens the fixed destination and follows the symbolic link. 6. The target file is overwritten with chart image data. Exploitation depends on the attacker having write access to the chart directory or control over the destination entry. The code alone does not grant that prerequisite. ### Impact Assessment The maximum write capability is bounded by the permissions of the account executing the skill. If it ...[truncated 649 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Avoid running the skill as root; use a dedicated account with only the permissions required to retrieve data and create charts. 2. Create a unique output file for each invocation using Python's `tempfile` facilities in a dedicated, access-controlled directory. 3. Set restrictive directory and file permissions, such as owner-only access where appropriate. 4. Do not reuse a global filename across users or concurrent requests. 5. If a stable destination is required, verify with `os.lstat()` that it is not a symbolic link and open it using operating-system protections such as `O_NOFOLLOW` and `O_EXCL`. 6. Write to a securely created temporary file and atomically rename it only after successful chart generation. 7. Return the generated path to the caller and delete temporary charts after delivery according to a defined retention policy. ]]>
Vulnerability Patterns
  • 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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (8)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The documented behavior promises accurate stock analysis across CN, HK, and US markets, but the implementation reportedly misclassifies Hong Kong tickers, outputs incorrect OHLC fields, and handles the chart artifact unclearly. In a financial-analysis context, materially incorrect market data and signals can mislead users into harmful financial decisions, making this more dangerous than a normal formatting bug.

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill instructs execution of a local Python script that uses both shell and network capabilities, but the manifest does not declare any tool scope or permission boundaries. This creates an authorization gap where the runtime may permit broader behavior than users or reviewers expect, reducing transparency and increasing the risk of misuse or unintended external access.

Vague Triggers

Medium
Confidence
96% confidence
Finding
The trigger phrases are broad enough that ordinary conversation about stocks may activate the skill without clear user intent, causing unsolicited script execution and network access. Because the skill provides financial analysis, accidental activation can also surface unrequested investment guidance, increasing user-risk and trust issues.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill produces buy/sell/hold recommendations without any disclaimer, suitability warning, or statement that the output is informational rather than personalized financial advice. In this context, users may over-rely on simplistic technical indicators and act on the recommendations, creating meaningful financial harm and compliance risk.

Natural-Language Policy Violations

Medium
Confidence
89% confidence
Finding
The trigger phrases, examples, and output template are written entirely in Chinese, and the skill does not state that this locale restriction is optional or region-specific. This can violate language/locale policy when a skill implicitly forces a specific language without user opt-in.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
This code performs a file write by saving a generated chart to /root/.openclaw/workspace/stock_chart.png. Although the operation is functional, the script does not warn the user up front that it will create or overwrite a file at a specific path; the only mention appears after the save succeeds.

Description-Behavior Mismatch

Medium
Confidence
92% confidence
Finding
The manifest describes a stock summary skill that returns real-time quote details, which implies correctly reporting quote components such as open, high, and low. However, these lines print the current price string again instead of the separately fetched open/high/low values, so the actual behavior does not match the claimed quote output.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
The module description and most user-facing output strings are presented only in Chinese, which effectively forces a specific language for interaction. Under the policy, language constraints should either offer user choice or be clearly justified as region-specific.

Static analysis

No suspicious patterns detected.