Back to skill

Security audit

Xueqiu Combo Report

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly coherent, but it needs review because it uses a logged-in financial browser session, persists portfolio-style data, and renders unescaped report data with Chrome sandboxing disabled.

Review before installing. Use it only with a trusted Xueqiu session and trusted input files, keep generated holdings reports out of shared or published repositories unless you intend to disclose them, and avoid PDF generation until the HTML escaping and Chrome sandboxing issues are fixed.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/build_report.py:76
Finding

Unescaped Report Data Is Rendered by Chrome with Browser Sandboxing Disabled

Content
View full analysis
{title} body {{ font-family: "Noto Sans CJK SC", "Microsoft YaHei", Arial, sans-serif; margin: 24px; color: #222; }} table {{ width: 100%; border-collapse: collapse; table-layout: fixed; margin: 12px 0 24px; font-size: 12px; }} th, td {{ border: 1px solid #999; padding: 6px 8px; vertical-align: top; word-break: break-word; }} th {{ background: #f3f3f3; }} @page {{ size: A4 landscape; margin: 12mm; }}

{title}

{note}

  • 组合总数:{output['comboCount']}
  • 成功纳入统计:{output['successComboCount']}
  • 失败组合数:{output['failureCount']}
  • 去重后股票数:{output['uniqueStockCount']}
'''] for i, item in enumerate(ranking, 1): combos_html = '
'.join( f'{c["combo_name"]}({c["combo_symbol"]},{c["weight"]}%)' for c in sorted(item['combos'], key=lambda x: (-x['weight'], x['combo_symbol'])) ) parts.append(f'') parts.append('
排名股票名称股票代码被持仓组合数量合计持仓比例所在组合及持仓比例
{i}{item["stock_name"]}{item["stock_symbol"]}{item["combo_count"]}{item["total_weight"]:.2f}%{combos_html}
') return '\n'.join(parts) def maybe_render_pdf(html_path: Path, pdf_path: Path): chrome = shutil.which('google-chrome-stable') or shutil.which('google-chrome') or shutil.which('chromium') or shutil.which('chromium-browser') if not chrome: return False, ...[truncated 3615 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (9)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The code chunk is a report generator, not an end-to-end workflow. It accepts an input JSON file, optionally patches combo entries, computes stock rankings, emits summary files, and invokes Chrome/Chromium headlessly to print HTML to PDF. There is no browser-session interaction, no Xueqiu scraping, no login-dependent collection, and no batch retrieval logic. The declared description overstates the implemented scope by including upstream data collection capabilities that are absent from this code.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents a full end-to-end analysis skill covering data collection, merge/patch, ranking, and multi-format export. The supplied code chunk is a narrow utility script for merging existing JSON batch files. It reads local JSON inputs, normalizes supported structures, deduplicates combo records and failures by combo_symbol, removes failures superseded by successes, and writes a normalized JSON file. This is only one sub-step of the described workflow, so the description materially overstates the code’s actual behavior.

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · references/end-to-end.md (reported line 80)May include surrounding context.

return {results, failures};

text

## Final output rule | 最终统计口径

Only keep stocks with `weight > 0` in the final ranking.  
最终排名里只保留 `weight > 0` 的股票。

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill instructs use of browser, file read/write, and shell-driven scripts, but it does not declare any explicit tool scope such as allowed-tools or permissions. That omission weakens least-privilege controls and can cause an agent runtime or reviewer to underestimate what the skill may access or modify, especially because the workflow includes persisted output and shell execution.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The workflow repeatedly tells the agent to save batch JSON files and commit workspace changes, but it does not warn that holdings data may be sensitive and persist locally or in version control. In a finance-related context, this increases the risk of unintended retention or disclosure of portfolio/interest data, especially if the workspace is synced, shared, or later published.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The document instructs users to run browser-side JavaScript that performs authenticated requests with credentials:'include' in an already logged-in Xueqiu session, but it does not clearly warn that this uses the user’s active session and may access account-scoped data. While the fetch target is same-origin and intended for data collection, normalizing copy-paste execution in an authenticated browser context increases the risk of accidental over-collection, data exposure, or unsafe adaptation of the pattern to less trusted contexts.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The script launches Chrome/Chromium in headless mode with --no-sandbox to render attacker-influenced HTML into PDF. Disabling the browser sandbox removes an important containment boundary, so if malformed or malicious content triggers a browser vulnerability, the impact on the host process can be significantly worse than normal PDF rendering.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/build_report.py (reported line 105)May include surrounding context.

python
chrome = shutil.which('google-chrome-stable') or shutil.which('google-chrome') or shutil.which('chromium') or shutil.which('chromium-browser')
    if not chrome:
        return False, 'No Chrome/Chromium binary found'
    subprocess.run([chrome, '--headless', '--disable-gpu', '--no-sandbox', f'--print-to-pdf={pdf_path}', html_path.resolve().as_uri()], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    return True, None

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The generated Markdown and HTML content uses fixed Chinese-language labels and sets the HTML document language to "zh-CN". This imposes a specific language/locale on all users, and the script does not offer a language choice or explain that it is intentionally region-specific.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.