Back to skill

Security audit

Tushare Daily Market Sense

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its A-share market-report purpose, but it needs review because it can mutate local/PostgreSQL market-data stores and a migration script can print database credentials.

Review before installing if you will run it against a real PostgreSQL database or in a workspace containing secrets. Use a dedicated low-privilege database, rotate any password that may have appeared in migration logs, avoid running from directories with unrelated .env files, and treat generated HTML as untrusted if report text can include external or user-supplied links.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/migrate_stock_to_pg.py:13
Finding

PostgreSQL Credentials Exposed Through Unredacted Logging

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/_shared/html_report/markdown_engine.py:21
Finding

Unsafe Markdown Link Schemes Permit Script Execution in Generated Reports

Content
View full analysis
str: escaped = html.escape(text) code_values: List[str] = [] def keep_code(match: re.Match[str]) -> str: code_values.append(f"{match.group(1)}") return f"@@CODE{len(code_values) - 1}@@" escaped = re.sub(r"`([^`]+)`", keep_code, escaped) escaped = re.sub(r"\*\*([^*]+)\*\*", r"\1", escaped) escaped = re.sub(r"(?\1", escaped) escaped = re.sub(r"\[([^\]]+)\]\(([^)]+)\)", r'\1', escaped) for idx, value in enumerate(code_values): escaped = escaped.replace(f"@@CODE{idx}@@", value) return escaped ``` ### Technical Analysis The renderer HTML-escapes Markdown text but inserts link destinations directly into an `href` attribute without validating the URL scheme. HTML escaping protects the surrounding markup but does not make dangerous schemes safe. For example: ```markdown [Open report details](javascript:alert(document.domain)) ``` is rendered as: ```html Open report details ``` If a reader clicks the link, the browser can execute JavaScript in the generated report's document context. Other risky schemes, including certain `data:` URLs, are also not rejected. The report Markdown is produced by an Agent and can potentially include user-supplied or externally derived text. Consequently, an attacker who can influence generated Markdown may be able to place a malicious link into the final HTML report. ### Attack Path 1. An attacker supplies content that is incorporated into the generated report, such as a crafted Markdown link. 2. The Agent preserves or reproduces that link in `report_YYYYMMDD.md`. 3. `rend ...[truncated 922 chars]
Remediation
View remediation

other

Note
Location
scripts/_shared/html_report/builder.py:33
Finding

Generated HTML Reports Initiate Undeclared Requests to Google Fonts

Content
View full analysis
\n' ' \n' ' ' ) ``` The links are inserted into every generated document: ```python out = f""" {escaped_title} {_FONT_LINKS} ``` ### Technical Analysis Opening a generated HTML report causes the browser to preconnect to and request resources from Google Fonts. This conflicts with the builder's description of the report as self-contained and with the Skill documentation stating that local HTML does not depend on an external CDN. These requests do not transmit the Tushare token, PostgreSQL DSN, evidence package, or report body according to the reviewed code. Nevertheless, the external provider can observe connection metadata such as the viewer's IP address, request time, browser characteristics, and potentially referrer behavior. The font requests are not necessary for market-data analysis or report generation and therefore exceed the minimum network privileges required by the declared functionality. ### Attack Path 1. The Skill generates an HTML report using `HtmlReportBuilder`. 2. The resulting document contains Google Fonts preconnect and stylesheet tags. 3. A user opens the report while connected to the network. 4. The browser contacts `fonts.googleapis.com` and `fonts.gstatic.com`. 5. Those services receive network and browser request me ...[truncated 746 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (36)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description presents a domain-specific market analysis/research skill focused on Tushare Pro A-share daily-data evidence generation. The supplied code does not implement any market-analysis logic, Tushare data handling, feature grouping, report generation, or stock-review methodology. Instead, it is a generic shared database access layer used to connect to PostgreSQL or SQLite, manage pools, mask DSNs, translate SQL placeholders, and ping tables. While such infrastructure could support the broader skill, this code chunk’s actual purpose is materially different from the declared end-user skill behavior and exposes undeclared capabilities around database connectivity and diagnostics. Therefore this chunk does not accurately represent the declared skill purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description says this skill should generate deterministic evidence packages for post-market A-share analysis using Tushare daily-related datasets. However, the actual code does not perform any market-data analysis, report generation, feature grouping, historical review, or stock observation logic. Its sole purpose is operational: checking DB connectivity and required tables. That is a materially different primary purpose and capability set. While the mentioned tables include stock-related data, the script only verifies their existence and connection status, which is infrastructure support rather than the described analytical methodology. Therefore this is a clear description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

声明描述的是一个面向 A 股盘后研究的领域分析 skill,核心应是读取/加工市场数据并生成确定性证据包与分析结论。而实际代码片段只是共享的 HTML report 包初始化文件,负责导出渲染相关组件,属于通用展示层基础设施。它与声明中的金融数据分析主目的明显不一致,也没有体现任何相关数据访问、计算或业务分析流程。尽管报告渲染可作为研报输出的支持实现细节,但该代码片段本身的实际作用与声明的核心能力存在明显偏离,因此应判定为描述与行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description is about a domain-specific financial analysis skill centered on Tushare Pro A-share daily data and market research methodology. The supplied code does not perform any market-data retrieval, financial analysis, evidence-pack construction, feature grouping, or stock observation logic. Instead, it is generic presentation infrastructure for building HTML reports from markdown with themes, chart hooks, and UI scripts. While such a component could support the broader skill as an implementation detail, this code chunk by itself has a materially different primary purpose and exposes undeclared capabilities related to HTML rendering and client-side report composition.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description says this skill is for A-share market post-close analysis based on Tushare Pro data, including trend analysis, sentiment, feature grouping, historical review, and quantitative observation workflows. The supplied code does none of that. It contains a generic markdown rendering utility for converting markdown text into HTML, with support for tables, lists, code blocks, headings, and inline styles. It does not access Tushare data, perform any stock or index analysis, generate evidence packages, or implement the described market-research methodology. This is not merely a supporting implementation detail tied closely to the declared purpose; it is a generic presentation-layer component with a materially different primary purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

声明描述的是一个面向 A 股盘后复盘与量化观察的金融分析 skill,核心能力应围绕行情数据获取、指标计算、特征分组和研报证据包生成。而提供的代码仅处理 Markdown 到 HTML 的文本保真验证:解析 HTML、忽略 script/style、标准化文本、抽取 Markdown 片段并检查是否在 HTML 可见文本中出现。其主要用途属于报告渲染/质量保障工具链,而非证券数据分析或研报生成。两者主用途明显不一致,因此应判定为描述与行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description is for an analytical research-generation skill focused on producing post-market evidence and structured market analysis from Tushare Pro daily data. The supplied code does not implement analysis, report generation, feature grouping, historical review logic, or quant observation outputs. Instead, it is an ETL utility whose primary purpose is migrating cached market data files into PostgreSQL. While the migrated data may support the declared analytical workflow, this code chunk itself is infrastructure for storage/import, not the described market-research methodology skill. Therefore the description does not accurately represent the actual behavior.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 29)May include surrounding context.

md
按需生成 HTML:当用户要求 HTML、网页、可视化报告或截图风格输出时,先完成并核对 `reports/report_YYYYMMDD.md`,再运行 `scripts/render_report_html.py` 生成同日期 HTML。HTML 是展示层产物,不新增研报判断、不删减 Markdown 正文;若同

Hidden Instructions

High
Category
Prompt Injection
Confidence
60% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · reference/market_data.csv (reported line 1)May include surrounding context.

text
日期,上涨,涨停,下跌,跌停,平盘,活跃度,成交额,融资净买入,全市场换手率
2026/05/15,1486,71.0,3932,46.0,99.0,,3134384000.0,7995515163.0,3.1584
2026/5/14,1047,82.0,4387,48.0,81.0,19.41%,3388086341.0,,3.1434
2026/5/13,3215,147.0,2134,17.0,167.0,,3264212322.0,21939951590.0,2.9745

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

Reading credentials from a .env file constitutes credential access, and here it is broader than necessary because it targets the current working directory rather than a narrowly scoped skill-owned location. In shared agent workspaces this can expose unrelated secrets if the process is launched from another repository or directory containing credentials.

Content

Scanner excerpt · scripts/market_panel.py (reported line 120)May include surrounding context.

python
if token:
        return token

    env_path = os.path.join(os.getcwd(), ".env")
    if not os.path.exists(env_path):
        return ""

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% 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).

Content

Scanner excerpt · scripts/render_report_html.py (reported line 41)May include surrounding context.

python
parser.add_argument("--evidence", default=None, help="Evidence JSON path. Defaults to sibling evidence_YYYYMMDD_utf8.json when input is report_YYYYMMDD.md.")
    parser.add_argument("--title", default=None, help="HTML document title.")
    parser.add_argument("--theme", default="default", choices=list_themes(), help="HTML style theme. default = Claude-UI; print = monochrome serif, A4-friendly.")
    parser.add_argument("--no-validate", action="store_true", help="Skip Markdown text preservation validation.")
    return parser

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/run_daily_panel.py (reported line 120)May include surrounding context.

python
@contextlib.contextmanager
def patched_environment(env: Dict[str, str]):
    original = os.environ.copy()
    try:
        os.environ.clear()
        os.environ.update(env)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill advertises and instructs use of environment variables, local file reads/writes, database access, and network-backed data retrieval, but it does not declare any explicit tool/permission scope. In an agent setting, this weakens least-privilege controls and can cause the skill to be run with broader capabilities than necessary, increasing the blast radius if the skill is misused or later modified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file presents all operational instructions exclusively in Chinese and does not indicate that users may choose another language or locale. Under the stated policy, forcing a specific language without opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

This markdown template begins with and consistently instructs output in Chinese, including explicit Chinese phrasing requirements such as “用一句人话定性今天的盘面.” Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is clearly documented and justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The entire template is written as prescriptive Chinese-language output format and wording, with no indication that users may choose another language. This creates a natural-language locale policy issue because it implicitly requires a specific language without opt-in or stated regional justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This markdown template presents all instructions and labels exclusively in Chinese, which can constitute a language/locale policy violation when no user choice or opt-in is offered. The file does not document that the skill is region-specific or otherwise justify the language restriction.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The file’s headings and authoring instructions are entirely in Chinese, including prescriptive output text such as '无候选时写:暂无命中。' and the required one-sentence judgment format. This creates a natural-language locale constraint with no indication that the user can opt into another language or that the skill is intentionally limited to a Chinese-language/regional use case.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

标题与整份文档内容均以中文撰写,且未说明这是区域性/合规性要求,也没有提供其他语言选项。根据规则,若技能文档强制特定语言而无用户选择或明确正当理由,属于语言/locale 策略违规。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The README’s instructional content is entirely in Chinese, including usage guidance and behavior descriptions, with no indication that language selection is optional or that the skill is intentionally restricted to a Chinese-speaking context. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The builder hard-codes lang: str = "zh-CN" as the default document language, which imposes a specific locale on all generated reports unless callers explicitly override it. This is a natural-language locale policy concern because the file does not indicate user choice or a documented region-specific justification for forcing Chinese locale by default.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest frames this skill as a methodology for generating post-market analysis evidence from Tushare-derived daily data, with emphasis on producing deterministic evidence packages. This file goes beyond read-only analysis by implementing multiple mutating operations against backend storage, including DELETE, TRUNCATE, and bulk INSERTs for daily frames, datasets, and market history.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The code performs a full-table destructive operation with TRUNCATE TABLE when writing unkeyed datasets, which can irreversibly remove existing data before reinserting replacement rows. Although the docstring mentions 'full replacement', there is no user-facing disclosure, confirmation prompt, or explicit warning near the destructive action itself.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This statement irreversibly clears the entire market_history table before re-inserting data. The function docstring says 'Replace market_history table contents', but there is no explicit user-facing warning, confirmation, or disclosure that all existing records will be deleted as part of the operation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Normal execution updates persistent reference CSV/JSON files or database state rather than acting as a read-only evidence generator. This side effect can poison future analyses, create nondeterministic outputs across runs, and let bad upstream data become long-lived local state.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.