Back to skill

Security audit

Break Watch

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to perform the promised stock scan, but it needs review because it installs unpinned Python packages and can write spreadsheet-like files using unsanitized remote market data.

Install only in an isolated Python environment, avoid installing the full requirements.txt unless pyinstaller is actually needed, and prefer pinned dependency versions. Treat generated .sel/CSV-like files as untrusted market-data exports and avoid opening them in formula-evaluating spreadsheet software unless the stock-name fields are sanitized. Invoke the scanner only for explicit scan requests, not general market discussion.

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

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Unpinned Third-Party Dependencies Create a Supply-Chain Risk

Content
View full analysis

Vulnerability Details

File Location: requirements.txt:1-2; related installation guidance at SKILL.md:15-22 and dynamic import at src/break_watch/tdx_client.py:124-130
Vulnerability Type: Unpinned and unhashed third-party dependencies
Risk Level: Medium

Vulnerable Code

requirements.txt:1-2

text
pytdx
pyinstaller

SKILL.md:15-22

bash
C:\Users\xfb\.workbuddy\binaries\python\versions\3.13.12\python.exe -m venv C:\Users\xfb\.workbuddy\binaries\python\envs\default
C:\Users\xfb\.workbuddy\binaries\python\envs\default\Scripts\pip install pytdx

src/break_watch/tdx_client.py:124-130

python
@staticmethod
def _create_api() -> Any:
    try:
        from pytdx.hq import TdxHq_API
    except ImportError as exc:
        raise TdxClientError(
            "pytdx is not installed. Run: .\\venv\\Scripts\\python.exe -m pip install -r requirements.txt"
        ) from exc

Technical Analysis

Both dependencies are specified without exact versions or package hashes. Consequently, installation resolves to whatever release the configured package index serves at installation time. The reviewed source code therefore does not fully define the code that will execute in the user's environment.

Python package installation can execute package build logic, while imported dependencies execute with the same privileges as the scanner. A compromised package release, compromised package-index account, dependency substitution through an untrusted index, or an incompatible future release could therefore alter the scanner's network and filesystem behavior.

pyinstaller is included in the runtime requirements even though it is not needed for the documented single-scan workflow. This unnecessarily expands the dependency and transitive supply-chain surface.

Attack Path

  1. An attacker compromises a future release, maintainer account, distribution channel, or package index used ...[truncated 1058 chars]
Remediation
View remediation

Remediation Suggestions

  1. Pin every direct dependency to a reviewed exact version, such as package==x.y.z.

  2. Generate a locked requirements file containing hashes for all direct and transitive dependencies.

  3. Install with hash verification, for example:

    bash
    python -m pip install --require-hashes -r requirements.lock
    
  4. Remove pyinstaller from runtime requirements. Place it in a separate build-only dependency file if executable packaging is required.

  5. Configure installation to use a trusted package index and prohibit unintended supplemental indexes.

  6. Periodically scan the lock file with software-composition analysis tools and review dependency updates before refreshing pins.

  7. Build and test dependencies in an isolated, least-privileged environment.

  8. Document the exact supported Python and dependency versions so users do not need to install an unspecified latest release.

T09 · Insecure Skill Coding Practices

Warning
Location
src/break_watch/output.py:88
Finding

Spreadsheet Formula Injection Through Remotely Supplied Stock Names

Content
View full analysis

Vulnerability Details

File Location: Remote input enters at src/break_watch/universe.py:188-192 and src/break_watch/tdx_client.py:145-147; unsafe spreadsheet serialization occurs at src/break_watch/output.py:88-94 and src/break_watch/output.py:132-151
Vulnerability Type: CSV/spreadsheet formula injection
Risk Level: Medium

Vulnerable Code

src/break_watch/universe.py:188-192

python
def _stock_from_security_item(market: int, item: dict[str, Any]) -> Stock | None:
    code = str(item.get("code", "")).strip()
    if not code.isdigit() or len(code) != 6:
        return None
    name = str(item.get("name", "")).strip()
    return replace(Stock(market=market, code=code), name=name)

src/break_watch/tdx_client.py:145-147

python
name = str(item.get("name") or stock.name or "").strip()
if name and name != stock.name:
    stock = Stock(market=stock.market, code=stock.code, name=name)

src/break_watch/output.py:88-94

python
def _append_csv(self, rows: list[dict[str, str]]) -> None:
    exists = self.csv_path.exists()
    with self.csv_path.open("a", newline="", encoding="utf-8-sig") as file:
        writer = csv.DictWriter(file, fieldnames=CSV_FIELDS)
        if not exists:
            writer.writeheader()
        writer.writerows(rows)

src/break_watch/output.py:132-151

python
@staticmethod
def _row(signal: Signal) -> dict[str, str]:
    return {
        "datetime": signal.timestamp.strftime("%Y-%m-%d %H:%M:%S"),
        "market": str(signal.stock.market),
        "code": signal.stock.code,
        "name": signal.stock.name,
        "price": f"{signal.price:.4f}",
        "last_close": f"{signal.last_close:.4f}",
        "open": f"{signal.open:.4f}",
        "change_pct": f"{signal.change_pct:.4f}",
        "current_volume": f"{signal.current_volume:.4f}",
        "avg_volume": f"{signal.avg_volume:.4f}",
        "expect
...[truncated 2861 chars]
Remediation
View remediation

Remediation Suggestions

  1. Treat every textual value obtained from TDX servers as untrusted.
  2. Add a dedicated spreadsheet-cell sanitizer before CSV serialization.
  3. Prefix values beginning with =, +, -, @, tab, or carriage return with an apostrophe or another format-appropriate neutralization character.
  4. Apply sanitization after trimming or canonicalization so leading whitespace cannot bypass the check.
  5. Keep raw values separate from presentation-safe values if exact source data must be preserved.
  6. Consider exporting a format that supports explicit text cell types when spreadsheet use is expected.
  7. Add regression tests covering values such as formula-prefixed names, leading whitespace followed by a formula marker, tabs, carriage returns, delimiters, quotes, and Unicode control characters.
  8. Retain the existing HTML escaping, which appropriately protects the HTML output context.
  9. Document that generated files contain remote market data and should not be opened in software that evaluates active content until sanitized.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (9)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description promises a functional stock-scanning skill with specific financial screening behavior and use of pytdx for real-time quotes. The supplied code does not implement any of these capabilities; it is only minimal package metadata. This is a material mismatch in primary purpose and actual behavior. There are no undeclared harmful capabilities evident in this snippet, but the declared functionality is absent from the code shown.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
81% confidence
Finding

The skill instructs the agent to create a Python virtual environment, install packages, and write outputs to a result directory, but it does not declare any explicit tool scope or permissions. That mismatch can cause the agent to perform filesystem-affecting actions without transparent authorization boundaries, increasing the risk of unintended file reads/writes or broader execution than users expect.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The trigger terms are very broad and include generic market words like '上涨', '阳线', '放量', and '量比', which can cause the skill to activate in many ordinary stock discussions. Over-broad activation increases the chance that the agent invokes code, network access, or file-producing workflows when the user did not intend to run this specific scanner.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

This markdown file presents all instructions and descriptions exclusively in Chinese, which can amount to a language/locale policy issue if users are not explicitly given a choice. The policy specifically calls for flagging content that forces a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The dependency pytdx is unpinned, so installs may pull different versions over time, including versions with undiscovered or newly disclosed vulnerabilities or breaking behavior. This weakens supply-chain integrity and makes builds non-reproducible, which is a real but generally low-severity security issue in a stock-scanning skill.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
pytdx
pyinstaller

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

pyinstaller is unpinned, allowing installation of an arbitrary latest-compatible release at build time. Because build/packaging tools execute in trusted environments and have had security advisories, leaving this dependency unpinned increases supply-chain and environment-compromise risk beyond a normal runtime library.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
pytdx
pyinstaller

Unverifiable Dependency: pyinstaller has 6 known advisory(ies) (CVE-2019-16784 (Local Privilege Escalation in PyInstaller); CVE-2023-49797 (Local Privilege Escalation in Windows); CVE-2025-59042 (PyInstaller has local privilege escalation vulnerability) +3 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The manifest includes pyinstaller without a version pin even though the package has multiple known advisories. Without a fixed version, there is no way to verify whether deployments will use a patched or vulnerable release, creating avoidable exposure in build or packaging workflows.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The HTML template sets lang="zh-CN", which imposes a specific language/locale in generated output. Under the policy, locale constraints should be user-selectable or clearly documented and justified; this file shows neither.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The error message instructs users to run '.\venv\Scripts\python.exe -m pip install -r requirements.txt', which assumes a Windows environment and specific locale/platform conventions. Under the policy for natural-language violations, forcing a specific environment or locale-sensitive path without user choice or justification can be considered a policy issue.

Content

No source excerpt is available for this finding.