Back to skill

Security audit

A股T+0基金5分钟级别买卖监控

Security checks for vulnerabilities and agentic risk

Overview

This fund-monitoring skill is mostly purpose-aligned, but it needs review because it can influence financial decisions using unauthenticated market data and stores trade history that is not clearly disclosed.

Install only if you are comfortable with a China-market fund monitor that fetches market data from third-party services, may send signal details to configured chat webhooks, and stores simulated trade history locally. Treat its alerts as untrusted informational signals, avoid running the installer or cleanup scripts as root, review webhook settings, and prefer pinned dependencies plus HTTPS-only market data before using it for real trading decisions.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (5)

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Unpinned and inconsistent third-party dependency installation<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1-6`; related installation commands in `install.sh:45-55` and `SKILL.md:25-33,46` **Vulnerability Type**: Supply-chain exposure through mutable dependency resolution **Risk Level**: Medium ### Vulnerable Code `requirements.txt:1-6`: ```text akshare>=1.10.0 pandas>=1.5.0 pandas-ta>=0.3.14b0 APScheduler>=3.9.0 requests>=2.28.0 pyyaml>=6.0 ``` `install.sh:45-55`: ```bash pip3 install akshare pandas APScheduler pyyaml -q 2>&1 | tee -a $LOG_FILE # 尝试安装 TA-Lib echo "" echo "5. 安装 TA-Lib..." if pip3 install TA-Lib -q 2>&1 | tee -a $LOG_FILE; then echo " ✅ TA-Lib 安装成功" else echo " ⚠️ TA-Lib 安装失败,尝试使用预编译包..." if pip3 install TA-Lib --only-binary :all: -q 2>&1 | tee -a $LOG_FILE; then ``` `SKILL.md:25-33`: ```yaml "install": [ { "id": "dependencies", "kind": "pip", "package": "akshare pandas pandas-ta APScheduler requests pyyaml", "label": "Install dependencies: pip3 install akshare pandas pandas-ta APScheduler requests pyyaml", }, ], ``` ### Technical Analysis The project installs packages without exact version pins or package hashes. The `>=` constraints allow any later release, while the direct `pip3 install` commands resolve the latest package versions available at installation time. The dependency definitions are also inconsistent. The Skill metadata requests `pandas-ta`, whereas `install.sh` installs `TA-Lib`. As a result, the effective dependency set depends on which installation method the user follows. This prevents reproducible security review and increases exposure to compromised releases, malicious maintainer updates, dependency substitution, and unexpected breaking changes. Python packages may execute code during build or installation, and imported packages execute module initialization code with the privileges of the invoking user. ### Attack Path 1. An attacker compromises a permitted dependency release, its maintainer ac ...[truncated 858 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace all lower-bound or unversioned dependencies with a single reviewed lock file containing exact versions. 2. Generate and verify cryptographic hashes for every package and transitive dependency. 3. Install with a command such as: ```bash python3 -m pip install --require-hashes -r requirements.lock ``` 4. Make `SKILL.md`, `install.sh`, and package metadata consume the same lock file rather than maintaining separate dependency lists. 5. Resolve the `pandas-ta` versus `TA-Lib` inconsistency and document the single supported indicator implementation. 6. Install dependencies inside a dedicated virtual environment under an unprivileged account. 7. Use a trusted package index explicitly and incorporate dependency vulnerability scanning into releases. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
tools/data_fetch.py:90
Finding
Market data used for financial signals is fetched over cleartext HTTP<![CDATA[ ## Vulnerability Details **File Location**: `tools/data_fetch.py:90-91` and `tools/data_fetch.py:147-148` **Vulnerability Type**: Missing transport confidentiality and integrity **Risk Level**: High ### Vulnerable Code `tools/data_fetch.py:90-91`: ```python url = f"http://hq.sinajs.cn/list={symbol}" r = session.get(url, timeout=5) ``` `tools/data_fetch.py:147-148`: ```python url = f"http://qt.gtimg.cn/q={symbol}" r = session.get(url, timeout=5) ``` The returned values are parsed and accepted as current market prices without cryptographic transport protection: ```python data = match.group(1).split(',') if len(data) < 10: return None name = data[0] open_price = float(data[1]) if data[1] else 0 close = float(data[3]) if data[3] else 0 high = float(data[4]) if data[4] else 0 low = float(data[5]) if data[5] else 0 prev_close = float(data[2]) if data[2] else 0 ``` ### Technical Analysis Both primary real-time quote providers are contacted through unauthenticated cleartext HTTP. HTTP provides no server authentication or response integrity. An attacker controlling a local network, DNS response, proxy, gateway, or upstream route can observe and modify the quote response. The application accepts the parsed values as trusted market data. These values are combined with K-line indicators and ultimately used to generate buy and sell notifications. Although the project does not place brokerage orders, users may act on its recommendations. Basic response-shape checks do not protect against deliberate manipulation because an attacker can return a syntactically valid quote containing forged prices and volumes. ### Attack Path 1. The victim starts monitoring a fund while connected through an attacker-controlled or compromised network. 2. The monitor requests a Sina or Tencent quote over HTTP. 3. The attacker intercepts the request or redirects it through DNS or routing manipulation. 4. The attacker returns a correctly formatted response containing forge ...[truncated 805 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Use provider endpoints that support HTTPS and reject any fallback to cleartext HTTP. 2. Disable redirects or validate every redirect target to ensure it remains on HTTPS and an approved provider hostname. 3. Retain normal TLS certificate and hostname verification; do not introduce `verify=False`. 4. Validate that the instrument identifier returned by the provider matches the requested code. 5. Apply plausibility controls to price, volume, timestamp, and percentage-change fields. 6. Compare sensitive quote values against an independent HTTPS source before generating high-confidence alerts. 7. Fail closed and clearly mark data unavailable when transport integrity cannot be established. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
tools/notifier.py:12
Finding
Unrestricted DingTalk webhook URL enables server-side request forgery<![CDATA[ ## Vulnerability Details **File Location**: `tools/notifier.py:12-23` and `tools/notifier.py:76-79` **Vulnerability Type**: Server-side request forgery through an unvalidated webhook destination **Risk Level**: Medium ### Vulnerable Code `tools/notifier.py:12-23`: ```python def send_dingtalk(webhook: str, title: str, text: str) -> bool: """发送钉钉通知""" try: headers = {'Content-Type': 'application/json; charset=utf-8'} data = { "msgtype": "markdown", "markdown": { "title": title, "text": text } } response = requests.post(webhook, headers=headers, data=json.dumps(data), timeout=10) return response.status_code == 200 except Exception as e: print(f"钉钉通知发送失败:{e}", file=sys.stderr) return False ``` `tools/notifier.py:76-79`: ```python if notify_cfg.get('dingtalk', {}).get('enabled'): webhook = notify_cfg['dingtalk'].get('webhook', '') if webhook: send_dingtalk(webhook, title, text) ``` ### Technical Analysis The configured DingTalk webhook is passed directly to `requests.post` without checking its scheme, hostname, port, resolved address, or redirect behavior. The function therefore operates as a generic outbound HTTP POST primitive rather than a DingTalk-specific notifier. Any actor able to modify `config/default.yaml` can direct requests to loopback services, private network hosts, link-local endpoints, cloud metadata services that accept the request method, or attacker-controlled servers. The request body includes fund code, name, price, signal reason, time, and confidence. This issue requires control over the local Skill configuration or an equivalent configuration-writing capability. It does not independently grant that access. ### Attack Path 1. An attacker gains the ability to alter the Skill configuration, such as through another local process running under the same account or an unsafe config ...[truncated 1051 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse the webhook with `urllib.parse.urlsplit`. 2. Require the `https` scheme and the exact approved DingTalk webhook hostname. 3. Validate the expected path prefix and reject embedded credentials, nonstandard ports, fragments, and malformed URLs. 4. Resolve the hostname and reject loopback, private, link-local, multicast, and reserved IP address ranges for both IPv4 and IPv6. 5. Disable redirects or repeat all validation after every redirect. 6. Consider storing only a DingTalk access token and constructing the approved URL internally. 7. Restrict configuration-file permissions to the owning account and avoid accepting notification URLs from untrusted input. 8. Apply equivalent destination validation to any future configurable webhook integration. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
tools/clean_data.sh:8
Finding
Cleanup utility can terminate unrelated processes through broad command-line matching<![CDATA[ ## Vulnerability Details **File Location**: `tools/clean_data.sh:8-12` **Vulnerability Type**: Overbroad process termination across application boundaries **Risk Level**: Medium ### Vulnerable Code ```bash # 停止监控 echo "1. 停止监控进程..." pkill -f "monitor.py start" 2>/dev/null && echo " ✅ 进程已停止" || echo " ⚠️ 无运行进程" rm -f $DATA_DIR/monitor.pid ``` ### Technical Analysis `pkill -f` matches a pattern against the complete command line of every process the invoking user is permitted to signal. It does not constrain the target to the PID stored by this Skill, the expected executable path, or the expected process owner. Consequently, any unrelated process whose command line contains `monitor.py start` can be terminated. The risk expands significantly if the cleanup script is run under an administrative account because the command may signal processes belonging to other users. This is a least-privilege violation: cleanup of one Skill should only stop the process instance created by that Skill. ### Attack Path 1. An unrelated legitimate process has `monitor.py start` in its command line, or an attacker deliberately launches a process with that text in its arguments. 2. A user runs the documented `tools/clean_data.sh` utility. 3. `pkill -f` searches all signalable processes rather than using the Skill's PID file. 4. Every matching process receives the termination signal. 5. Unrelated monitoring or application workloads are stopped. 6. If cleanup runs with elevated privileges, processes owned by other accounts may also be affected. ### Impact Assessment The primary impact is denial of service against unrelated processes running under the same account. When invoked with elevated privileges, the scope may include system-wide processes owned by other users. The command does not grant the attacker new execution privileges, but it crosses process-isolation boundaries beyond those required by the Skill. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Read the PID from the Skill-specific PID file instead of using `pkill -f`. 2. Require the PID file to contain digits only. 3. Before signaling, verify: - The process exists. - The process is owned by the expected user. - `/proc/$pid/cmdline` or an equivalent platform API points to this project's `tools/monitor.py start`. 4. Send `SIGTERM` only to the validated PID and wait for graceful shutdown. 5. Use `SIGKILL` only after a bounded timeout and another identity check. 6. Quote all path variables: ```bash rm -f "$DATA_DIR/monitor.pid" ``` 7. Refuse to run the cleanup utility as root unless administrative operation is explicitly required and documented. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
install.sh:5
Finding
Installer writes to a predictable shared temporary-file path<![CDATA[ ## Vulnerability Details **File Location**: `install.sh:5-7`; writes occur at `install.sh:45,50,55,78` **Vulnerability Type**: Unsafe temporary-file handling and symlink-following risk **Risk Level**: Low ### Vulnerable Code `install.sh:5-7`: ```bash SKILL_DIR=~/.openclaw/skills/fund-monitor LOG_FILE=/tmp/fund-monitor-install.log ``` Representative write at `install.sh:45`: ```bash pip3 install akshare pandas APScheduler pyyaml -q 2>&1 | tee -a $LOG_FILE ``` Additional writes use the same path: ```bash if pip3 install TA-Lib -q 2>&1 | tee -a $LOG_FILE; then ``` ```bash if pip3 install TA-Lib --only-binary :all: -q 2>&1 | tee -a $LOG_FILE; then ``` ```bash if python3 -c "import akshare, pandas, apscheduler, yaml" 2>&1 | tee -a $LOG_FILE; then ``` ### Technical Analysis The installer appends to a fixed file in the globally writable `/tmp` directory. It does not securely create the file, check whether it is a symbolic link, verify ownership, or assign restrictive permissions. On systems where symbolic links are followed for this operation, another local user may pre-create `/tmp/fund-monitor-install.log` as a symlink to a file writable by the installer account. When `tee -a` opens the path, it may append dependency output to the symlink target. The impact is strongly dependent on operating-system hardening, target permissions, and the privileges used to run the installer. ### Attack Path 1. A local attacker predicts the fixed path `/tmp/fund-monitor-install.log`. 2. Before installation, the attacker creates that path as a symbolic link to another file. 3. A more privileged user runs `install.sh`. 4. `tee -a` opens the predictable path and follows the link where platform protections permit it. 5. Installer output is appended to the attacker-selected target. 6. The resulting file modification may corrupt configuration or another writable file; the log output may also become accessible outside the intended account. ### Impact Assessment Unde ...[truncated 495 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create the log using `mktemp` rather than a predictable filename: ```bash umask 077 LOG_FILE="$(mktemp "${TMPDIR:-/tmp}/fund-monitor-install.XXXXXX.log")" ``` 2. Register a cleanup trap if the log does not need to persist: ```bash trap 'rm -f "$LOG_FILE"' EXIT ``` 3. Quote every reference to the path: ```bash tee -a "$LOG_FILE" ``` 4. If a persistent log is required, store it in a user-owned directory with mode `0700` and create the file with mode `0600`. 5. Refuse symbolic links and verify file ownership before every append. 6. Do not run the installer or `pip` as root; use a dedicated virtual environment under an unprivileged account. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (37)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
A second, distinct mismatch exists where the skill reportedly persists trade history, tracks open positions, and simulates a trade lifecycle despite presenting itself as a monitoring/signal tool. Undeclared stateful financial behavior can mislead users about what data is stored and what decisions are being modeled, creating both security and integrity risks in a finance-related context.

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding
A second, distinct mismatch exists where the skill reportedly persists trade history, tracks open positions, and simulates a trade lifecycle despite presenting itself as a monitoring/signal tool. Undeclared stateful financial behavior can mislead users about what data is stored and what decisions are being modeled, creating both security and integrity risks in a finance-related context.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
# 停止监控
echo "1. 停止监控进程..."
pkill -f "monitor.py start" 2>/dev/null && echo "   ✅ 进程已停止" || echo "   ⚠️ 无运行进程"
rm -f $DATA_DIR/monitor.pid

# 清理数据
echo ""
Confidence
95% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
# 清理数据
echo ""
echo "2. 清理数据文件..."
rm -f $DATA_DIR/trades.json && echo "   ✅ 交易记录已清理"
rm -f $DATA_DIR/signals.json && echo "   ✅ 信号历史已清理"
rm -f $DATA_DIR/watchlist.json && echo "   ✅ 监控列表已清理"
Confidence
95% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
echo ""
echo "2. 清理数据文件..."
rm -f $DATA_DIR/trades.json && echo "   ✅ 交易记录已清理"
rm -f $DATA_DIR/signals.json && echo "   ✅ 信号历史已清理"
rm -f $DATA_DIR/watchlist.json && echo "   ✅ 监控列表已清理"

# 清理日志
Confidence
95% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
echo "2. 清理数据文件..."
rm -f $DATA_DIR/trades.json && echo "   ✅ 交易记录已清理"
rm -f $DATA_DIR/signals.json && echo "   ✅ 信号历史已清理"
rm -f $DATA_DIR/watchlist.json && echo "   ✅ 监控列表已清理"

# 清理日志
echo ""
Confidence
95% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
# 清理日志
echo ""
echo "3. 清理日志..."
rm -f $LOGS_DIR/monitor.log && echo "   ✅ 日志已清理"

# 保留配置
echo ""
Confidence
95% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The entire skill documentation is presented only in Chinese, including operational steps, warnings, and FAQs, with no indication that users may choose another language or that the skill is intentionally limited to a Chinese-speaking or region-specific audience. This can violate language/locale policy requirements because it effectively forces a specific language without user opt-in.

Lp3

Medium
Category
MCP Least Privilege
Confidence
83% confidence
Finding
The skill advertises install and execution steps that imply shell, network, and local file capabilities, but it declares no explicit tool scope or permission boundaries. In an agent ecosystem, this increases the risk that the skill is invoked with broader access than users expect, enabling package installation, remote data access, and local state changes without clear consent or containment.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The trigger phrases are broad enough to match ordinary conversation about funds or monitoring, which can cause unintended invocation of a skill with shell, file, and network capabilities. In this context, accidental activation is more dangerous because the skill appears capable of installing dependencies, fetching remote data, and modifying local state.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
All user-facing comments and echo output are in Chinese, with no indication that the skill is intentionally limited to a Chinese-speaking audience or region. This creates a language policy issue because the skill enforces a locale without user opt-in or documented justification.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The installer performs unauthenticated network package installation with pip3 and does not explicitly warn the user that it will download and install code from external repositories into the local Python environment. This is risky because package installs execute supply-chain trust decisions at install time and can modify the system or user environment unexpectedly, especially when versions are unpinned and no hashes or virtual environment are used.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The script irreversibly deletes multiple state and log files and terminates matching processes without any confirmation, dry-run mode, or guardrails. In a maintenance script this is not necessarily malicious, but it is operationally dangerous because accidental execution can wipe monitoring history and stop active jobs immediately.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
The script's user-facing text and comments are entirely in Chinese, including status messages the user will see during execution. This imposes a specific language/locale without offering choice or documenting a justified region-specific constraint, which matches the policy-violation category for natural-language locale restrictions.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The natural-language title and user-facing messages in this file are presented in Chinese only, and there is no indication that the user can select a preferred language or that the language restriction is intentional and documented. This can violate language/locale policy when a skill forces a specific language without user opt-in.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
with open(PID_FILE, 'r') as f:
                    pid = int(f.read().strip())
                import subprocess
                result = subprocess.run(['ps', '-p', str(pid)], capture_output=True)
                process_running = (result.returncode == 0)
            except:
                process_running = False
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

External Transmission

Medium
Category
Data Exfiltration
Content
"content": f"### {title}\n{content}"
            }
        }
        response = requests.post(url, json=data, timeout=10)
        return response.status_code == 200
    except Exception as e:
        print(f"企业微信通知发送失败:{e}", file=sys.stderr)
Confidence
80% 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
95% confidence
Finding
The file’s docstrings and all formatted output strings are written in Chinese, including user-visible signal and trade messages. This imposes a specific language/locale without any opt-in, selection mechanism, or documented regional justification.

Description-Behavior Mismatch

Medium
Confidence
92% confidence
Finding
The file does more than generate monitoring signals: it also creates, updates, and closes trade records on disk via process_signal(), load_trades(), and save_trades(). This expands the skill from passive analytics into stateful trade-tracking behavior that users may not expect from the manifest, increasing privacy and integrity risk if records are inaccurate, retained unexpectedly, or consumed by other components as authoritative trading history.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
Trade history is written to a local JSON file without any disclosure, consent flow, or visibility to the user. Even if the data is 'only' fund codes, prices, and timestamps, it can reveal sensitive investment interests and behavior, and unprotected local persistence increases exposure to accidental leakage or reuse by other tools/users on the same system.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
The note '统一设置为 Asia/Shanghai' requires all platforms to use a specific timezone. This is a locale constraint stated as a requirement, but the document does not offer user choice or explain why this region-specific setting is necessary.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
This YAML file contains all comments and human-readable descriptions in Chinese, which imposes a specific language on users and maintainers without indicating that language selection is optional. Under the policy, forcing a language or locale without user opt-in is a natural-language policy concern.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
This JSON file contains user-facing explanatory text in Chinese in the "reason" fields and product names, but there is no indication that the skill offers a language choice or that the locale is intentionally limited. Under the language/locale policy rule, forcing a specific language without user opt-in can be a policy concern.

Unpinned Dependencies

Low
Category
Supply Chain
Content
akshare>=1.10.0
pandas>=1.5.0
pandas-ta>=0.3.14b0
APScheduler>=3.9.0
Confidence
95% confidence
Finding
The dependency akshare is specified with a minimum version only, which makes builds non-reproducible and allows later releases to be installed without review. While this is not an immediate exploit by itself, it increases supply-chain risk if a future compromised or incompatible version is pulled in.

Unpinned Dependencies

Low
Category
Supply Chain
Content
akshare>=1.10.0
pandas>=1.5.0
pandas-ta>=0.3.14b0
APScheduler>=3.9.0
requests>=2.28.0
Confidence
97% confidence
Finding
pandas is unpinned and can resolve to different versions over time, including versions with known or newly introduced vulnerabilities. This creates uncertainty in the deployed security posture and makes incident response and patch validation harder.

Static analysis

No suspicious patterns detected.