T09 · Insecure Skill Coding Practices
- Location
scripts/workbench_server.py:372- Finding
Disabled TLS Certificate and Hostname Verification for Market Data
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill’s financial-screening purpose is mostly coherent, but its optional local workbench has unauthenticated rerun controls, unsafe HTML rendering, and weakened market-data TLS that warrant Review before installation.
Install only if you are comfortable with an optional local financial-data workbench that writes files in your working directory and runs bundled scripts. Keep the server stopped when not actively using it, do not expose it through a proxy or LAN share, and treat results as untrusted until the endpoint authentication, CSRF protection, HTML escaping, and TLS verification issues are fixed.
scripts/workbench_server.py:372Disabled TLS Certificate and Hostname Verification for Market Data
scripts/report_html.py:115Stored HTML and DOM-Based Cross-Site Scripting Through Unescaped Market and Announcement Data
scripts/workbench_server.py:479Unauthenticated State-Changing Local Endpoint Executes the Screening Pipeline
The skill is presented as an analysis/checklist tool, but it also copies files into the user's working directory, checks ports, launches subprocesses, and starts a local web service. That is a meaningful expansion of behavior and attack surface: local service deployment and process spawning can persist beyond the original task and expose data or create unexpected system-side effects.
The skill is presented as an analysis/checklist tool, but it also copies files into the user's working directory, checks ports, launches subprocesses, and starts a local web service. That is a meaningful expansion of behavior and attack surface: local service deployment and process spawning can persist beyond the original task and expose data or create unexpected system-side effects.
The skill says it must not guide users to connect Wind, yet elsewhere instructs users to connect Wind or other MCPs for certain strategies. Contradictory trust-boundary guidance is dangerous because it can lead an agent to nudge users into enabling external data connectors despite a stated restriction, undermining platform safety controls around trusted integrations.
Referenced artifact was not completely inspected
**实时工作台**——一个零依赖的本地 Python 服务(`workbench_server.py` + `workbench_realtime.html`),
Referenced artifact was not completely inspected
**实时工作台**——一个零依赖的本地 Python 服务(`workbench_server.py` + `workbench_realtime.html`),
Referenced artifact was not completely inspected
**实时工作台**——一个零依赖的本地 Python 服务(`workbench_server.py` + `workbench_realtime.html`),
Referenced artifact was not completely inspected
**实时工作台**——一个零依赖的本地 Python 服务(`workbench_server.py` + `workbench_realtime.html`),
Referenced artifact was not completely inspected
**实时工作台**——一个零依赖的本地 Python 服务(`workbench_server.py` + `workbench_realtime.html`),
The resource description says AVPRICE is the intraday average-price line, but earlier text explicitly warns that AVPRICE is not the true average-price line and must not be used that way. This inconsistency can directly cause incorrect financial decisions by reintroducing a known bad calculation path into downstream code or operator understanding.
The /api/run endpoint launches multiple external Python scripts on demand, which is a significant execution capability not reflected in the stated checklist purpose. If a local attacker, another process, or a browser-based localhost request can hit this endpoint, the skill can be abused to execute additional code paths and perform filesystem writes under the user's context.
The skill documents capabilities that perform shell execution, network access, and file writes, but the manifest does not declare any tool scope or permission boundaries. That creates an authorization gap: an agent or reviewer cannot easily determine what actions are intended, increasing the chance of over-privileged execution or unsafe invocation of local scripts and networked workflows.
This markdown file describes that the skill may later add '自动化买卖操作', which is a safety-critical behavior because it could place trades affecting user assets. Although the document includes a general 'not investment advice' disclaimer, it does not specifically warn that automated execution would require explicit user authorization, careful validation, and risk controls before any live trading action.
The documentation extends a checklist skill into a local interactive web service that can rerun screening pipelines autonomously. Even if intended for convenience, adding a long-lived local service increases exposure to misuse, accidental invocation, and unintended persistence compared with a simple one-shot analysis skill.
This script is not limited to checklist analysis: it copies executable assets into whatever directory the user runs it from and then starts a local server there. That expands the skill's operational scope from analysis into deployment and local process execution, which can surprise users, alter their filesystem, and create persistence-like artifacts in arbitrary locations.
The module docstring is entirely in Chinese and includes an explicit suggested command to say to the agent in Chinese ("对 Agent 说「跑 Wind 核查」"). This creates a language/locale constraint in the skill's natural-language interface without any opt-in or alternative language path, which matches the policy violation criteria.
The file-copying and process-launching behavior gives the skill environment-modifying capabilities unrelated to a pure technical-analysis checklist. Even without obvious malware behavior, arbitrary-directory writes plus server startup increase the attack surface by creating executable content in user-chosen locations and opening a listening service on the host.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
print(f"\n🚀 启动工作台:http://127.0.0.1:{PORT}/")
print(f" 按 Ctrl+C 停止。\n")
try:
subprocess.run([sys.executable, server, str(PORT)], cwd=cwd)
except KeyboardInterrupt:
print("\n已停止工作台。")
This code file contains natural-language instructions and output entirely in Chinese, including the module description and later console messages, without offering any language selection or documenting a justified region-specific constraint. That creates a language/locale policy issue under the rule for natural-language policy violations.
The HTML document declares lang="zh-CN", and the full interface text is presented in Chinese, which imposes a specific language/locale on users. The file does not provide any visible opt-in, language selector, or justification that this skill is intended only for a China-specific audience.
The file exposes a persistent local HTTP service and browser workbench that materially expands the skill's attack surface beyond a simple checklist/analysis function. Even though it binds to 127.0.0.1, any local process or malicious webpage via localhost access can potentially trigger behavior, making the skill more powerful than users may expect from the manifest.
The manifest states the skill can use Tencent Finance API for objective prescreening metrics, and optionally Wind MCP for additional checks. This backend instead describes and performs reruns using Eastmoney prescreening/intraday endpoints and Sina K-line retrieval, indicating the actual implementation differs from the manifest-described data-source behavior.
The module docstring says the judgment logic strictly reuses report_html.py to guarantee identical conclusions. In practice, this file defines its own verdict, is_st, build_deep, and trade_plan logic locally, so the stated reuse guarantee is contradicted by the implementation and may drift over time.
An HTTP endpoint causes local code execution and writes multiple JSON artifacts without any authentication, confirmation gate, or visible consent mechanism in the backend. In the skill context, this is more dangerous because the endpoint is exposed through a browser workbench, increasing the chance of accidental triggering or localhost abuse by other local software.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
log = []
try:
# 1) select_stocks
r1 = subprocess.run([VENV_PY, os.path.join(SKILL, "select_stocks.py")],
cwd=CWD, capture_output=True, text=True, timeout=180)
log.append(r1.stdout.strip().splitlines()[-3:] if r1.stdout else [])
if r1.returncode != 0:
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
if r1.returncode != 0:
log.append("select_stocks stderr: " + r1.stderr[:500])
# 2) kline_history --top 40 --json
r2 = subprocess.run([VENV_PY, os.path.join(SKILL, "kline_history.py"),
"--top", "40", "--json"],
cwd=CWD, capture_output=True, text=True, timeout=300)
log.append(r2.stdout.strip().splitlines()[-3:] if r2.stdout else [])