Back to skill

Security audit

TZZB Analyzer - Tonghuashun Portfolio Analyzer

Security checks for vulnerabilities and agentic risk

Overview

This skill appears to be a real portfolio-analysis tool, but it uses an authenticated browser session and stores sensitive financial data locally with limited user-facing controls.

Review this before installing if you use Tonghuashun with real accounts. Run it only in a dedicated Chrome profile/session, assume it can read account holdings, trades, and relevant 10jqka cookies, and clean or protect the data/ and memory/ directories. Avoid enabling the cron examples until you are comfortable with repeated account-data collection and local report retention.

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

Warning
Location
scripts/analyze.py:476
Finding

Plaintext Persistence and Distribution of Sensitive Financial Data

Content
View full analysis

Vulnerability Details

File Location: scripts/analyze.py:430-431, scripts/analyze.py:476-482, scripts/report.py:852-860; sensitive generated artifacts are present in data/positions.json:4-24 and data/report_close_20260325.md:8-49
Vulnerability Type: Plaintext storage of sensitive financial information
Risk Level: Medium

Vulnerable Code

python
# scripts/analyze.py:430-431
out = {"type": "positions", "positions": raw}
print(json.dumps(out, ensure_ascii=False, indent=2))
(DATA_DIR / "positions.json").write_text(
    json.dumps(out, ensure_ascii=False, indent=2),
    encoding="utf-8",
)
python
# scripts/analyze.py:476-482
# Save the analysis and raw portfolio data.
(DATA_DIR / "analysis_report.json").write_text(
    json.dumps(analysis, ensure_ascii=False, indent=2),
    encoding="utf-8"
)
(DATA_DIR / "positions.json").write_text(
    json.dumps(raw.get("positions", {}), ensure_ascii=False, indent=2),
    encoding="utf-8"
)
python
# scripts/report.py:852-860
report_path = DATA_DIR / f"report_{args.mode}_{datetime.now().strftime('%Y%m%d')}.md"
report_path.write_text(report, encoding="utf-8")
print(f"Report saved: {report_path}")

if args.feishu:
    feishu_data = format_feishu_card(report)
    feishu_path = DATA_DIR / f"report_{args.mode}_{datetime.now().strftime('%Y%m%d')}_feishu.json"
    feishu_path.write_text(
        json.dumps(feishu_data, ensure_ascii=False, indent=2),
        encoding="utf-8",
    )

The distributed artifact demonstrates the type of persisted data:

json
{
  "overview": {
    "total_asset": 10007.98,
    "total_value": 1052.0,
    "money_remain": 8955.98,
    "total_liability": 0.0
  },
  "items": [
    {
      "stock_code": "300098",
      "hold_count": 200,
      "cost_price": 5.21,
      "current_price": 5.26,
      "market_value": 1052.0,
      "hold_profit": 7.98
    }
  ]
}

Technical Analysis

The Skill retrieves confidential investment-account information and writes it t ...[truncated 2643 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove generated financial records from distribution

    • Delete committed or packaged data/*.json, data/*.md, and Feishu-format output files.
    • Add generated financial files and dated reports to .gitignore and package-exclusion rules.
    • Add a release check that rejects artifacts containing portfolio or transaction data.
  2. Make persistence explicit and optional

    • Process account data in memory by default.
    • Require an explicit option such as --save-sensitive-data before writing raw positions or transactions.
    • Clearly disclose which data is retained, its location, and its retention period.
  3. Minimize retained data

    • Store only the values required by the monitor rather than complete raw account responses.
    • Avoid retaining transaction details, balances, quantities, or cost basis when they are not required.
    • Support redacted reports that omit exact balances and transaction amounts.
  4. Apply restrictive filesystem controls

    • Create sensitive files with owner-only permissions, such as mode 0600 on POSIX systems.
    • Create sensitive directories with mode 0700.
    • Avoid relying solely on the process umask.
    • Refuse to store sensitive output in a world-readable or shared directory unless the user explicitly confirms.
  5. Protect and expire retained records

    • Encrypt cached financial data using a user-managed key or operating-system credential store.
    • Implement automatic expiration and secure deletion where supported.
    • Provide a command that removes all cached portfolio data and reports.
  6. Reduce terminal disclosure

    • Avoid printing complete raw portfolio and transaction objects by default.
    • Provide a redacted summary mode for logs and scheduled executions.
    • Ensure cron or agent logs do not retain complete financial reports indefinitely.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (46)

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding

A mismatch between a benign-sounding analysis description and a browser-session data-scraping implementation materially changes the risk profile. In this context, the danger comes less from missing analysis features and more from the hidden emphasis on privileged browser access to retrieve account information.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
84% confidence
Finding

A mismatch between a benign-sounding analysis description and a browser-session data-scraping implementation materially changes the risk profile. In this context, the danger comes less from missing analysis features and more from the hidden emphasis on privileged browser access to retrieve account information.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

A mismatch between a benign-sounding analysis description and a browser-session data-scraping implementation materially changes the risk profile. In this context, the danger comes less from missing analysis features and more from the hidden emphasis on privileged browser access to retrieve account information.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

A mismatch between a benign-sounding analysis description and a browser-session data-scraping implementation materially changes the risk profile. In this context, the danger comes less from missing analysis features and more from the hidden emphasis on privileged browser access to retrieve account information.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

A mismatch between a benign-sounding analysis description and a browser-session data-scraping implementation materially changes the risk profile. In this context, the danger comes less from missing analysis features and more from the hidden emphasis on privileged browser access to retrieve account information.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

extract_cookies() collects and returns authentication cookies for .10jqka.com domains from the user's browser session. Authentication cookies are bearer tokens; exposing them to the agent or downstream components can enable full session hijacking and account access far beyond the manifest's stated analysis purpose.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
83% confidence
Finding

The skill advertises code-execution-adjacent capabilities (env access, file read/write, network, shell) but does not declare any explicit tool scope or permissions boundary. That makes the trust model unclear and can enable over-broad access to sensitive local data or external systems, especially given the browser-debug and report-generation workflows described.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill handles highly sensitive financial portfolio, watchlist, and trade-history data, yet the description does not clearly warn about privacy implications, browser-session access, or possible external data transmission. Users may therefore expose regulated or highly personal financial information without informed consent.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This markdown file contains user-facing instructions and analysis entirely in Chinese, but does not indicate that the user opted into that language or that the skill is limited 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
84% confidence
Finding

The entire skill output is presented only in Chinese, including headings, operational guidance, and disclaimer text, with no indication that the user selected this language or that the skill is limited to a Chinese-speaking context. The policy for natural-language content requires either user choice/opt-in or a clearly documented and justified locale constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This JSON config contains multiple user-facing alert names and messages entirely in Chinese, such as the alert names and recommendation text. The policy for all file types says to flag language or locale constraints when the skill forces a specific language without user opt-in, and this file provides no alternative locale or selection mechanism.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module description, CLI messages, and generated report text are entirely in Chinese, which imposes a specific language on all users. Under the stated policy, locale/language constraints should either be optional, user-selectable, or explicitly documented as justified.

Content

No source excerpt is available for this finding.

Internal Network Request

Medium
Category
Server-Side Request Forgery
Confidence
70% confidence
Finding

Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.

Content

Scanner excerpt · scripts/analyze.py (reported line 103)May include surrounding context.

python
def check_status():
    try:
        import urllib.request
        resp = urllib.request.urlopen("http://127.0.0.1:9222/json", timeout=5)
        tabs = json.loads(resp.read())
        return {"ok": True, "tabs": len(tabs), "details": tabs}
    except Exception as e:

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest describes a tool for reading portfolio data, combining it with market data, and generating analysis reports with risk monitoring and threshold alerts. However, the CLI also exposes a separate monitor command that imports and runs another monitoring module, which is a broader operational capability than the documented read/analyze/report workflow in this file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script writes sensitive financial data, including positions and generated analysis, to local files under data/ without an explicit warning, consent flow, retention policy, or permission hardening. On shared systems or environments where the skill directory is accessible to other users, this can expose account holdings, balances, and trading-related information beyond the immediate session.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The module docstring, CLI help text, generated report titles, and user-facing messages are all hard-coded in Chinese, with no option for users to select another language or locale. This is a natural-language policy concern because the skill imposes a specific language experience rather than making it opt-in or configurable.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The active docstring and immediate return at L099-L103 state that news is not fetched here and must be passed via --news, yet the same function includes a second embedded docstring and unreachable implementation for fetching remote RSS feeds. This creates direct contradiction in the file's documented intent versus the code present.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest emphasizes reading holdings/watchlists/trade records and generating analysis, but this implementation persists full report outputs under the skill's data directory. That goes beyond a purely read/analyze behavior by introducing durable local writes of account-derived content.

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 file contains natural-language descriptions and usage text entirely in Chinese, and the generated reports and user-facing messages throughout the script are also fixed to Chinese. Under the policy rule for language/locale, a skill should not force a specific language unless it offers opt-in or clearly documents a justified regional constraint.

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/report.py (reported line 59)May include surrounding context.

python
def _run_cmd(cmd: list, timeout=30) -> str:
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
        return result.stdout.strip()
    except Exception:
        return ""

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/report_backup_v2.3.py (reported line 59)May include surrounding context.

python
def _run_cmd(cmd: list, timeout=30) -> str:
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
        return result.stdout.strip()
    except Exception:
        return ""

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script accesses highly sensitive brokerage positions and trade records through an automated browser session, but there is no explicit user-facing notice, consent prompt, or data-handling disclosure in the relevant flow. In a financial context, silent collection and processing of account data increases privacy and trust risk, especially if combined with logging, persistence, or downstream sharing.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The docstring says news data is only passed in via the --news parameter and that the function merely validates parameters and returns an empty list. However, the same function contains contradictory inline documentation and implementation for fetching Eastmoney RSS over the network, even though it is currently unreachable because of the earlier return.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script persists generated reports and Feishu-formatted payloads to local disk under the skill data directory, and those files contain brokerage holdings, cash balance, positions, and trade activity. This creates a confidentiality risk because sensitive financial data is stored at rest without any user-facing disclosure, retention controls, or protection guarantees.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The saved report files contain sensitive portfolio and transaction information and are written automatically without a clear disclosure or confirmation. In this skill context, that increases the chance of unintended local exposure through backups, shared machines, other processes, or later exfiltration by unrelated components.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.