Back to skill

Security audit

小果聚宽策略量化助手

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real JoinQuant trading-code helper, but it includes live-capable automated trading examples and risky code patterns that need careful review before use.

Install only if you specifically want a JoinQuant trading-code assistant. Treat generated and reference strategies as live-capable code: review every order, cash-transfer, margin, file-read/write, network, credential, and messaging line before running it; avoid copying pickle loads, HTTP data fetches, hardcoded secrets, or unpinned third-party source into a real account.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
assets/2022年度精选策略.txt:5666
Finding

Unsafe Deserialization of Mutable Research Files

Content
View full analysis

Vulnerability Details

File Locations:

  • assets/2022年度精选策略.txt:5666-5669
  • assets/2023年度精选策略.txt:7967
  • assets/2024年度精选策略上.txt:14213-14214
  • assets/2024年度精选策略下.txt:8177-8178
  • assets/2024年度精选策略下.txt:12849
  • assets/2025年度精选策略.txt:6408

Vulnerability Type: Unsafe Python pickle deserialization
Risk Level: High

Vulnerable Code

python
col = pickle.load(BytesIO(read_file("col_50etf_20191109.dat")))
model = pickle.load(BytesIO(read_file("model_50etf_20191109.dat")))
python
tmp_df_dic = pickle.loads(read_file('test_predict_300_q.pkl'))
python
g.model = pickle.loads(read_file('model/xgboost_technical.pkl'))
python
g.model_zb = pickle.loads(read_file(g.model_zb_path))
g.model_cyb = pickle.loads(read_file(g.model_cyb_path))
python
g.model = pickle.loads(read_file('model_baseline.pkl'))

Technical Analysis

Python's pickle.load() and pickle.loads() are code-capable deserialization operations. A pickle stream may define reduction functions that invoke arbitrary Python callables during loading. Consequently, loading a pickle is equivalent to executing code supplied by whoever controls the serialized file.

The affected strategies read model and data files from JoinQuant research storage without authenticating their contents or restricting the object types that may be reconstructed. The vulnerability becomes exploitable if an attacker can upload, replace, share, or otherwise influence one of the referenced .pkl or .dat files.

Attack Path

  1. An attacker constructs a malicious pickle whose deserialization routine invokes an arbitrary Python callable.
  2. The attacker causes the malicious file to be stored under a referenced filename, such as model_baseline.pkl or test_predict_300_q.pkl. This may occur through a malicious shared project, a replaced research artifact, or unauthorized access to mutable research storage.
  3. The ...[truncated 854 chars]
Remediation
View remediation

Remediation Suggestions

  • Do not deserialize untrusted or mutable files with Python pickle.
  • Store tabular data in CSV, Parquet, or another non-code-bearing format.
  • Use a model format designed for the relevant framework that does not reconstruct arbitrary Python objects.
  • If legacy pickle files are unavoidable, distribute them from a controlled source and verify a pinned SHA-256 digest or digital signature before deserialization.
  • Restrict write access to research artifacts and do not accept model files from untrusted shared projects.
  • Document the expected filename, cryptographic digest, model type, and trusted publisher.
  • Treat hash verification as an integrity control rather than a substitute for trusted provenance.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:6668
Finding

Mutable and Unpinned Python Source Acquisition

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:6668-6674
Vulnerability Type: Unpinned third-party source-code dependency
Risk Level: Medium

Vulnerable Instruction and Code

The documentation instructs the user to download or copy mpl_finance.py from the mutable master branch, upload it to the research environment, and import it:

text
https://github.com/matplotlib/mpl-finance/blob/master/mpl_finance.py
python
import warnings
warnings.filterwarnings("ignore")
import mpl_finance

Technical Analysis

The URL is a GitHub repository page, not a personal pastebin, and the Skill does not automatically download or execute it. Nevertheless, it directs users to acquire executable Python source from a mutable branch without identifying a release, commit, cryptographic digest, or signature.

Importing a Python module executes its module-level statements. Therefore, the effective code that users execute may change after the Skill package has been audited. Suppressing warnings also makes unexpected behavior or compatibility problems less visible, although warning suppression is not itself a code-execution vulnerability.

Attack Path

  1. The upstream repository, maintainer account, or mutable branch is compromised or changed.
  2. The content served as mpl_finance.py is modified to include unwanted module-level behavior.
  3. A user follows the Skill documentation and copies or downloads the current file.
  4. The user uploads the file to the JoinQuant research environment.
  5. The generated or copied strategy executes import mpl_finance.
  6. Python executes the modified module-level payload with the permissions of the research process.

Impact Assessment

A compromised source file could execute arbitrary Python within the research runtime. It could access files and APIs available to that process, manipulate analysis results, alter strategy behavior, or initiate network operations ...[truncated 184 chars]

Remediation
View remediation

Remediation Suggestions

  • Replace the mutable master URL with an audited release or immutable commit URL.
  • Publish and verify a SHA-256 digest for the exact source file.
  • Prefer a maintained package already supplied by the platform.
  • If manual vendoring is required, include the reviewed file in the project with its license and provenance rather than retrieving it at runtime or during setup.
  • Do not globally suppress warnings while validating a newly introduced dependency.
  • Re-audit the dependency whenever its pinned version or digest changes.

T09 · Insecure Skill Coding Practices

Warning
Location
assets/2024年度精选策略上.txt:20903
Finding

Unauthenticated Plain-HTTP Retrieval of Trading Inputs

Content
View full analysis

Vulnerability Details

File Locations:

  • assets/2024年度精选策略上.txt:20903-20917
  • assets/2024年度精选策略上.txt:28076-28100

Vulnerability Type: Plaintext network transport and insufficient response validation
Risk Level: Medium

Vulnerable Code

python
def get_etf_value(stockcode):
    stockcode = stockcode[:6]
    url = "http://etf.eastmoney.com/" + stockcode + ".html"
    response = requests.get(url)
    etfDataInfo = response.text
    tmp_str = "fix_dwjz  bold ui-color-green"
    init_position = etfDataInfo.find(tmp_str)
    if init_position == -1:
        return -1
    else:
        init_position = etfDataInfo.find(tmp_str) + len(tmp_str)
        etf_value = float(etfDataInfo[init_position + 2:init_position + 8])
        return etf_value
python
url = "http://yield.chinabond.com.cn/cbweb-pbc-web/pbc/historyQuery"
params = {
    "startDate": start_date,
    "endDate": end_date,
    "gjqx": "10",
    "qxId": "hzsylqx",
    "locale": "cn_ZH",
}
headers = {
    "User-Agent":
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
        "AppleWebKit/537.36 (KHTML, like Gecko) "
        "Chrome/79.0.3945.130 Safari/537.36",
}
res = requests.get(url, params=params, headers=headers)
data_text = res.text.replace("&nbsp", "")
data_df = pd.read_html(data_text, header=0)[1]

Technical Analysis

Both functions obtain financial inputs over unauthenticated HTTP. HTTP provides neither server authentication nor transport integrity, allowing an on-path attacker to observe and alter responses.

The requests also omit bounded timeouts. The Eastmoney request does not call raise_for_status(), and both implementations trust brittle HTML parsing without sufficiently validating the returned schema, date, origin, or plausible value range. These weaknesses can cause manipulated or malformed responses to be treated as legitimate financial data.

External market-data ...[truncated 1482 chars]

Remediation
View remediation

Remediation Suggestions

  • Use HTTPS endpoints exclusively and verify TLS certificates.
  • Add explicit connection and read timeouts, for example timeout=(3, 10).
  • Call raise_for_status() before parsing a response.
  • Validate content type, response size, expected table structure, requested dates, instrument identifiers, and numerical ranges.
  • Reject stale, missing, malformed, or implausible values and fail closed rather than trading on them.
  • Prefer JoinQuant-native or authenticated structured-data APIs where equivalent data is available.
  • Add retry logic with strict limits and backoff, while preserving a safe no-trade fallback.
  • Log the source, retrieval time, and validation result without recording credentials or other sensitive data.
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
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (153)

YARA rule 'agent_skill_mcp_tool_poisoning_metadata': MCP/tool metadata poisoning indicators in tool schemas or skill manifests [agent_skills]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

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

md
---
name: 小果聚宽量化交易助手
description: |
  小果(微信 xg_quant)聚宽量化交易助手-聚宽(JoinQuant)量化平台策略生成与辅助工具。根据用户需求,生成可在聚宽平台运行的 Python 量化交易策略代码,提供 API 使用指导、常见问题排查与策略优化建议。
  触发关键词:聚宽、JoinQuant、JQ、写策略、生成策略、量化策略、回测代码、模拟交易、双均线、网格交易、因子选股、Alpha因子、多因子、取数据、财务数据、聚宽API、聚宽报错。
  作者:小果
  联系方式:微信 xg_quant
version: 2.0.0
m

Hidden Instructions

High
Category
Prompt Injection
Confidence
88% confidence
Finding

The matched hidden character strongly suggests an invisible Unicode character embedded in the document. In an agent skill, hidden characters can be used to disguise instructions, evade pattern matching, or make human review diverge from model interpretation, which is more concerning given this skill already contains extensive executable guidance.

Content

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

md
目标函数(target) 优化目标函数,只能选择一个
MinVariance(count=250) - 组合风险最小化(最小化组合方差)

​ 最小化组合方差

参数:

Ae5

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Instruction-capable artifact exceeds whole-file semantic analysis limits

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The multiline comment at L00057-L00059 describes the file as an assistant for code hints, optimization, and strategy modification. However, the surrounding code initializes globals and in handle_data invokes stock filtering and logs execution timing inside an actual JoinQuant strategy runtime, and elsewhere in the same file multiple sections place live orders and rebalance holdings. This is an active contradiction between the stated intent and the implemented behavior.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

At L00160-L00161 and many later repeated docstrings, the file claims to provide training/support for strategy development rather than execute trades. In contrast, numerous functions throughout the file call order_target, order_value, order_target_value, purchase, redeem, set_subportfolios, and other APIs to trade stocks, ETFs, funds, and futures. This is clear intent-code divergence rather than mere incomplete documentation.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

This section explicitly acknowledges possible future-data bias and then uses cached next-day minute data for same-day selection logic in backtests. That creates look-ahead leakage, producing materially misleading performance and potentially causing users to trust a strategy that cannot work in live trading.

Content

No source excerpt is available for this finding.

Ae5

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Instruction-capable artifact exceeds whole-file semantic analysis limits

Content

No source excerpt is available for this finding.

Ae5

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Instruction-capable artifact exceeds whole-file semantic analysis limits

Content

No source excerpt is available for this finding.

Ae5

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Instruction-capable artifact exceeds whole-file semantic analysis limits

Content

No source excerpt is available for this finding.

YARA rule 'agent_skill_mcp_tool_poisoning_metadata': MCP/tool metadata poisoning indicators in tool schemas or skill manifests [agent_skills]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · assets/2024年度精选策略上.txt (reported line 14695)May include surrounding context.

text
归曲线中$𝑃_{𝑙𝑜𝑤}后面出现一个极大值点,则把当日作为卖出点$𝑃_{𝑠𝑒𝑙𝑙}$;
# 6. 如果下跌幅度超过10%则触发止损条件,卖出股票;
# 7. 对于其他极小值点-极大值点组合,重复上述过程。
# 
# 除了找到极值点用到了核回归的结果,其他步骤用的都是实际的价格数据.
# 
# ![avatar](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA2sAAAEXCAYAAAAzytwDAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAP+lSURBVHhe7J0HYBzF1cf/10+9d1nFtixZcu+9gMGFYsCmdwIESIBAgPClkEJCgBQgISQQIJTQWyimg3uvsuUmW733ruu333tze/KpuklYxvODtW7LzM6+mZ03b+bNrEYhIJFIJJJuWCwWGI1G6HQ69cixwdVqc3MzQkJC1CP9h9vtFptGo+kzXXyNy+US12i1WvXo6YHNZoPJZFL3jg4/J8tcr9erRwYGu90Op9MJf39/9ch3C997oJ/xdONMkAk/49He997gd4nrMA4vkUhOT6SxJpFIJBKJRCKRSCSDkNOru1UikUgkEolEIpFIzhCksSaRSCQSiUQikUgkg5BubpDrBmCOhUQikUgkvsxqalJ/nTxSb0kkEolksDOrsZEsr+OfP9rNWFstJ6FKJBKJZICZ24/TpaXekkgkEslgZ67bfULGmnSDlEgkEolEIpFIJJJBSLeRNVdzs/pLIpFIJJKBQRccrP46eaTe

YARA rule 'privilege_escalation_tools': Privilege escalation tools and techniques [hacktools]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · assets/2024年度精选策略上.txt (reported line 14695)May include surrounding context.

text
jASSUyxobCCBv16P0lIDGhrd9PucHw/0l5dBt/n3swy02i5trZf8Lz6nyJ+rPP+a51xCYjzdbz2RtFB8+pMfw6YtW3Dq9FlMsNkgW6045jc7ukwhAkZkrY7uy035c6BVPeVxgvf5Ato26V1YON6G/HodylsNRNY99zHQMu76DrmN8Pvj7e7eYV9l4MtfJ2mQlsbrmTpgMrlx4UII8vI0sAmSze2Vu4seyniA9YzRqfx7LQPOfxj7y57ypzwog4v566ivKC26IPIbaUhOS8biRXZ+FJw8ZRBhOviR6NZHLPzLOojAQkNjniE5Say7dtbVI/bjDyLqlpvFuea330XHH/6EOdSHcZDrAupPDtP4xJ5sOcC1mdo2hxzhusRu+aNNLtSzVv0aiw02EBjGpSPyphv/f3vnARhHcb3x74ruTl22muUq9wbYBgzGdGOqqaETMBhCQnrIHxJKQiAkhBJCKAESSAidBDAdbEwCxMa4Yhv3bsnqktXLnXTl/765O/skS0KSVe33k9e3fWdnd+fNN/NmBlFpqWZ4ivIP5xmhbGdaFkpDDmUi02Ol62lq8w6UXtl1v8/bAMdB2BCUGS5XwCVZMGZwgKG+IUgJJAczLAELhvqHmO3M/ORbC00tGTNj1ZYabLftMMcQdugRhjVk3IeEfzsDftjpkujNufZqbNy0BW+9815oS/M0V7NmqoDlZXWNG2sMV9269Sbnwox18pWXI/mqK8x2Zrv4qlQvWoy8Bx4yx7JL44GzZmBEzmJEu8vxdW4UCquZ6HY8k9ZazdrFItbmRseKwG3/+dlxyR8fvA+rVn+N555/MbS2Z2DwQ9EuvwEMHBgcoDsz04eEeBH3OTbTQcWWrcFftp3pDbB2kh2HHD99Gr744kvTM6kzJK6ZmRwtGZpYeUcaiTV3HTZL3NPFhVCsWWWf9bIP7ypBMjhThzRga4kNu8s6p0YtTKQY6wh0dRw71odBg73wNlhE6EeZTmQopql1OjGo

Ae5

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Instruction-capable artifact exceeds whole-file semantic analysis limits

Content

No source excerpt is available for this finding.

Ae5

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Instruction-capable artifact exceeds whole-file semantic analysis limits

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The file interleaves executable strategy code with natural-language explanations, and at this location the explanation does not match the adjacent code. In an agent skill, that mismatch can mislead downstream users or tools into trusting behavior that is materially different from what will actually run, causing unsafe execution decisions or bypass of review expectations.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The module docstring describes the file as a learning/support assistant, but the code actually initializes a live trading strategy, schedules automated tasks, selects securities, and places sell/buy orders. This mismatch can mislead reviewers or downstream systems into granting the file more trust than warranted, which is especially dangerous in a financial execution context where hidden autonomous behavior can cause real monetary loss.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The stated purpose claims training/support only, while the implementation performs autonomous stock screening and trade execution through functions such as run_monthly, order_target, and order_value. In a skill ecosystem, deceptive capability labeling weakens security review and can lead operators to run code they believe is non-executing advisory logic when it is in fact financially active.

Content

No source excerpt is available for this finding.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding

Suspicious Unicode normalization or mixed-script content

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger keyword list is overly broad for a skill that can generate live or simulated trading code, increasing the chance of accidental activation in unrelated conversations. In this context, mis-triggering is more dangerous because the skill can steer users toward high-risk financial automation and order-placement workflows without a deliberate opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill prominently teaches strategy generation and trading APIs but does not provide a clear up-front warning that generated code may execute order placement, cash transfer, messaging, file I/O, and other impactful actions in backtest or live-like contexts. In a financial-trading skill, this omission materially increases user harm because users may run generated code without understanding operational and financial consequences.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

At L0402 the documentation explicitly states '未在策略中保存跨日期的行情数据缓存' as a safety check item. Later, the example at L6005-L6006 stores historical price data in g.last_df, and g is documented elsewhere in the same file as persisted across process restarts, which conflicts with the earlier safety guidance and models a cross-date cache pattern.

Content

No source excerpt is available for this finding.

Context Window Stuffing

Medium
Category
Memory Poisoning
Confidence
80% confidence
Finding

Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Content

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

md
get_money_flow('000001.XSHE', '2015-10-01', '2015-12-30', fields="change_pct")
get_money_flow(['000001.XSHE'], '2010-01-01', '2010-01-30', ["date", "sec_code", "change_pct", "net_amount_main", "net_pct_l", "net_amount_m"])

# — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

# 获取多只股票在一个时间段内的资金流向数据
get_money_flow(['000001.XSHE', '000040.XSHE', '000099.XSHE'], '2010-01-01', '2010-01-30')

Context Window Stuffing

Medium
Category
Memory Poisoning
Confidence
80% confidence
Finding

Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Content

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

md
get_money_flow('000001.XSHE', '2015-10-01', '2015-12-30', fields="change_pct")
get_money_flow(['000001.XSHE'], '2010-01-01', '2010-01-30', ["date", "sec_code", "change_pct", "net_amount_main", "net_pct_l", "net_amount_m"])

# — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

# 获取多只股票在一个时间段内的资金流向数据
get_money_flow(['000001.XSHE', '000040.XSHE', '000099.XSHE'], '2010-01-01', '2010-01-30')

Context Window Stuffing

Medium
Category
Memory Poisoning
Confidence
80% confidence
Finding

Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Content

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

md
get_money_flow('000001.XSHE', '2015-10-01', '2015-12-30', fields="change_pct")
get_money_flow(['000001.XSHE'], '2010-01-01', '2010-01-30', ["date", "sec_code", "change_pct", "net_amount_main", "net_pct_l", "net_amount_m"])

# — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

# 获取多只股票在一个时间段内的资金流向数据
get_money_flow(['000001.XSHE', '000040.XSHE', '000099.XSHE'], '2010-01-01', '2010-01-30')

Context Window Stuffing

Medium
Category
Memory Poisoning
Confidence
80% confidence
Finding

Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Content

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

md
# 直接还 1000 股平安银行
marginsec_direct_refund('000001.XSHE', 1000)

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

## 如果账户持仓中"没有" 1000股 平安银行
# 需先买入 1000 股平安银行

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The code contains a direct authentication call for jqdatasdk, indicating credential-based external access is expected in code. Even though the sample shows empty strings, hardcoded auth patterns normalize insecure secret handling and can lead to accidental credential leakage when reused with real values.

Content

No source excerpt is available for this finding.