Back to skill

Security audit

小果可转债量化分析助手

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly matches a quant-analysis tool, but it handles credentials insecurely and includes under-scoped remote mutation and custom-code-style API capabilities.

Review before installing. Only use this with a trusted server and test credentials unless the transport is changed to HTTPS and secrets are removed from query strings and logs. Do not let an autonomous agent call deletion, community publishing/simulation, or get_user_def_data without explicit confirmation and a clear understanding of the remote account permissions.

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

Error
Location
SKILL.md:5242
Finding

Credentials Transmitted and Logged Through Plaintext HTTP Query Strings

Content
View full analysis
Dict[str, Any]: """Build request parameters and automatically add authentication information.""" params = { 'user': self.user, 'password': self.password, 'auth_code': self.auth_code, } params.update(kwargs) return params def _request( self, endpoint: str, params: Dict[str, Any], method: str = 'GET', timeout: Optional[int] = None, verbose: bool = True ) -> Dict[str, Any]: if timeout is None: timeout = self.timeout url = f"{self.base_url}{endpoint}" clean_params = {k: v for k, v in params.items() if v is not None} try: if method.upper() == 'GET': response = self.session.get( url, params=clean_params, timeout=timeout ) else: response = self.session.post( url, params=clean_params, timeout=timeout ) if verbose: print(f"Request URL: {response.url[:100]}...") print(f"Status code: {response.status_code}") ``` ### Technical Analysis The client uses unencrypted HTTP while automatically adding the user's password and authorization code to every request. For GET requests, `requests` serializes these values into the URL query string. The POST branch also uses the `params` argument, so its credentials are likewise placed in the query string rather than the request body. This design creates two related exposure channels: 1. Plaintext HTTP provides no transport confidentiality or server authentication. An attacker capable of observing or modifying t ...[truncated 1745 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/xg_factor_trader.py:306
Finding

Unsanitized Security Identifiers Permit Filesystem Path Traversal

Content
View full analysis
0: save_path = r'{}/data/全部因子数据/{}.parquet'.format( self.path, stock ) os.makedirs(os.path.dirname(save_path), exist_ok=True) df.to_parquet(save_path, compression='zstd') ``` The same unsanitized write pattern also appears in `_calculate_single_stock_sync()`: ```python if df.shape[0] > 0: save_path = r'{}/data/全部因子数据/{}.parquet'.format( self.path, stock ) os.makedirs(os.path.dirname(save_path), exist_ok=True) df.to_parquet(save_path, compression='zstd') return True ` ...[truncated 2809 chars]
Remediation
View remediation
Path: if not SECURITY_CODE.fullmatch(identifier): raise ValueError("Invalid security identifier") resolved_base = base.resolve() candidate = (resolved_base / f"{identifier}.parquet").resolve() if not candidate.is_relative_to(resolved_base): raise ValueError("Path escapes the authorized data directory") return candidate ``` 4. Use separate fixed base directories for historical data, index data, and generated factor data. 5. Perform the containment check immediately before each read, directory creation, and write operation. 6. Do not rely on `os.path.exists()` as a security validation mechanism. 7. Run the Skill under a dedicated, least-privileged operating-system account with write access only to its intended output directory. 8. Add tests covering parent-directory traversal, absolute paths, platform-specific separators, symbolic links, malformed identifiers, and unexpected filename suffixes. 9. Consider opening output files through a controlled directory handle or using platform-specific no-follow protections where symbolic-link attacks are within the threat model. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (49)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

代码核心功能是从本地 parquet/Excel 文件读取证券与指数数据,调用 xg_factor 中的因子函数,批量生成并保存“全部因子数据”。证券列表来源不仅有可转债代码,还包含基金代码,因此其实际覆盖对象并非仅可转债。虽然这与“因子数据”部分声明相符,也属于量化分析基础设施的一部分,但声明中的几个核心能力——尤其是策略回测、组合分析——在本代码块中没有出现。也未看到专门的可转债历史行情查询接口或面向用户的分析助手能力。因此描述对能力范围和主要用途存在明显夸大与偏移,应判定为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

从代码看,核心内容是大量技术分析函数与通达信兼容函数,如 MA、EMA、MACD、KDJ、RSI、BOLL、SAR、ZIG、DMI、OBV 等,以及交易信号函数(如 MA_交易、MACD_交易、KDJ_交易)和公式解析工具 params_data。代码没有展示任何可转债特有对象、字段、数据源、转股溢价率、纯债价值、双低值、强赎/回售条款、可转债池管理等专属分析逻辑;也没有看到历史行情抓取、因子数据库、回测执行器、组合优化或组合绩效分析模块。虽然这些通用技术分析函数可被用于金融研究,但其实际行为与“专注于可转债量化分析工具,提供可转债历史行情数据、因子数据、策略回测、组合分析等核心功能”的声明存在明显能力差异,且代码主要面向通用技术指标与公式转换,因此应判定为描述与实际行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

从代码看,核心行为是:从本地 parquet 文件读取“历史数据”和“指数数据”,按日期过滤,做简单复权和涨跌幅计算,然后把单个标的与指数数据传入 xg_factor 模块,计算一个技术信号(MACD_金叉),最后输出日期、证券代码、证券名称和因子值。这更像通用证券/股票因子计算测试脚本。声明则强调可转债量化分析助手,包含可转债历史行情、因子数据、策略回测、组合分析等多个核心功能。当前代码既没有明确处理可转债专属逻辑,也没有展示回测、组合分析等能力,且示例标的“513100.SH”并不像可转债代码。因此描述与代码实际行为存在明显不匹配。

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The client builds base_url with plain http:// and automatically includes user, password, and auth_code in request parameters, which are then transmitted without transport encryption. This exposes credentials and query contents to interception by any network observer or intermediary, making account compromise and sensitive data leakage likely in real deployments.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill exposes destructive deletion and bulk-deletion operations for strategy data that are not justified by the stated analytics purpose. If invoked accidentally or maliciously, these endpoints can destroy user or community strategy records and disrupt operations, especially because they are mixed into an otherwise analysis-oriented interface.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

get_user_def_data forwards arbitrary user-supplied code-like content (func) to a remote service, effectively exposing remote code or script execution capability under the guise of a data helper. In the context of a convertible-bond analysis assistant, this is highly dangerous because it enables execution of attacker-controlled logic on backend infrastructure and can lead to data exfiltration, lateral movement, or service compromise.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The implementation contradicts its documented purpose: under the async branch, the code performs only data loading and persistence while presenting the operation as full factor computation. This mismatch is dangerous because users of a quant-analysis skill are likely to rely on the outputs for research or automated trading, and the defect is silent rather than obvious.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The async branch inside the method advertised as computing all stock factors only loads stock data and writes it directly to the factor output directory, without invoking any factor-calculation logic. This can silently produce incorrect 'factor' datasets that downstream backtests, signals, or portfolio decisions may trust as valid, creating a serious integrity risk in a quantitative trading workflow.

Content

No source excerpt is available for this finding.

Whitespace Padding

High
Category
Prompt Injection
Confidence
80% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/xg_factor.txt (reported line 2029)May include surrounding context.

text
'''逆势操作 - AL'''
        cdp_val, ah_val, nh_val, nl_val, al_val = CDP_STD(CLOSE=self.C, HIGH=self.H, LOW=self.L)
        return al_val

Whitespace Padding

High
Category
Prompt Injection
Confidence
80% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · scripts/xg_factor.py (reported line 2029)May include surrounding context.

python
'''逆势操作 - AL'''
        cdp_val, ah_val, nh_val, nl_val, al_val = CDP_STD(CLOSE=self.C, HIGH=self.H, LOW=self.L)
        return al_val

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The method docstring for cacal_all_stock_factor_single claims it performs staged single-thread factor calculation for all stocks. Yet when use_async_io is enabled and enough symbols are present, the implementation uses get_stock_data and immediately saves the returned dataframe, without computing factors via xg_factor or _call_factor_function, contradicting the stated behavior.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest describes a convertible-bond quantitative analysis assistant centered on factor data and backtesting-related analytics, but in the async branch of cacal_all_stock_factor_single the code only preloads stock data with get_stock_data and writes that dataframe directly to 全部因子数据 without invoking any factor computation. This means a documented factor-calculation workflow can silently produce outputs lacking the promised factor columns.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest says the skill is a 专注于可转债量化分析助手 with core functions around convertible-bond行情、因子、回测和组合分析. However, the embedded documentation and implemented client expose broad capabilities for stocks, ETFs, indices, minute K-line data, and multiple categories of general stock financial statements, which materially exceeds the claimed convertible-bond-specific scope.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The top-level class documentation presents the client as a data API and backtest integration framework. Later methods include deletion of single and all strategy records, which contradicts the documented read/analysis framing by adding destructive management behavior.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The implementation includes strategy publication, simulation, and community-management operations that materially exceed an analytics assistant's advertised scope. Hidden management capabilities increase the chance that users or agents invoke state-changing operations unexpectedly, especially in environments where the skill is trusted for read-only analysis.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill does not clearly warn users that destructive deletion endpoints are available, which is dangerous because an analysis-focused skill creates a read-only expectation. In context, this increases the risk of accidental destructive invocation by users or autonomous agents that trust the advertised purpose.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code writes user-facing labels directly in Chinese ("红色", "蓝色", "买", "卖") and does not provide any option to select another language or locale. That creates a language policy issue because the skill behavior is effectively hard-coded to one language without documented user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

These lines populate output columns such as "柱子", "笑脸", and "标记文字" using Chinese-only labels. Because the file contains user-visible natural-language outputs but no mechanism for user language choice, it violates the language/locale policy criteria.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

At L0392-L0394 the method KDJ_KD死叉 is documented as KDJ_KD金叉 的 Docstring, which describes a golden cross. However, L0396 computes CROSS(D,K), i.e. the opposite direction consistent with a dead cross, so the inline documentation contradicts the implementation.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The method RSI_死叉 at L0407-L0413 carries the docstring RSI_金叉 的 Docstring, indicating a golden cross. But L0412 computes CROSS(RSI2,RSI1), which is the inverse crossing direction and matches a dead-cross signal instead.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

In MACD_死叉, the docstring at L0441-L0443 still says MACD_金叉 的 Docstring. The implementation at L0445 uses CROSS(DEA,DIF), which represents the opposite signal direction from a golden cross, so the documentation actively contradicts the code.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The function PSY_死叉 is documented at L0457-L0459 as PSY_金叉 的 Docstring, implying a golden cross. Yet L0461 computes CROSS(PSYMA,PSY_1), which is the opposite crossing direction and corresponds to a dead cross.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The worker writes computed factor data to parquet files under the skill data directory, which can overwrite prior results for the same stock. Although force-recalculation behavior is documented elsewhere, this write path itself provides no user-facing disclosure or confirmation before modifying files.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The params_data helper reads an arbitrary local file path and writes a transformed output file path, which exceeds the stated purpose of a convertible-bond analytics assistant and creates an unnecessary filesystem write primitive. Even without code execution in this snippet, arbitrary file transformation and overwrite behavior can be abused to modify local files, clobber user data, or stage follow-on attacks if exposed through the skill.

Content

No source excerpt is available for this finding.