Back to skill

Security audit

Factorlab

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed A-share stock factor-analysis tool, but users should treat its outputs as research signals rather than investment advice.

Install only if you are comfortable with an A-share research tool that may contact TDX market data servers and may use simulated data when live data is unavailable. Use a virtual environment, consider pinning pytdx before installation, and do not treat its buy/sell wording as personal financial advice.

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
SKILL.md:30
Finding

Unpinned Third-Party Dependency Installation

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:30-35
Vulnerability Type: Unpinned package installation and software supply-chain exposure
Risk Level: Medium

Vulnerable Code:

bash
pip install pytdx

Technical Analysis

The installation instruction retrieves the currently resolved version of pytdx and its transitive dependencies without a version constraint, cryptographic hash verification, or lockfile. Consequently, the code installed by this command can change after the Skill has been reviewed.

If the package, one of its dependencies, or the configured package index is compromised, following this instruction could install attacker-controlled code. Python packages may execute code during installation and will execute imported module code when the Skill uses pytdx.

Attack Path

  1. An attacker compromises a future pytdx release, a transitive dependency, or the package distribution channel.
  2. A user follows the documented pip install pytdx instruction.
  3. The package resolver downloads the compromised release because no reviewed version or hash is required.
  4. Attacker-controlled code executes during installation or when factorlab_engine.py imports pytdx.hq.
  5. The malicious code operates with the privileges of the user running pip or the analysis script.

Impact Assessment

Successful exploitation could provide arbitrary code execution under the installing user's account. Depending on that account's permissions, an attacker could access user-readable files and credentials, modify files, establish network connections, or tamper with analysis output. The project itself does not contain evidence that pytdx is currently malicious; the risk arises from unsafe dependency resolution.

Remediation
View remediation

Remediation Suggestions

  • Pin pytdx to a specifically reviewed version in a dependency manifest.
  • Generate a lockfile that also fixes all transitive dependency versions.
  • Require cryptographic hashes during installation, for example:
    bash
    python -m pip install --require-hashes -r requirements.txt
    
  • Configure an explicit trusted package index or an internally controlled package mirror.
  • Review and update pinned dependencies through a controlled process with vulnerability and provenance checks.
  • Recommend installation inside a dedicated virtual environment using a non-privileged account.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/factorlab_engine.py:549
Finding

Incorrect Live-Data Provenance Reporting After Connection Teardown

Content
View full analysis

Vulnerability Details

File Location: scripts/factorlab_engine.py:549-569
Vulnerability Type: Data provenance and integrity error
Risk Level: Low

Vulnerable Code:

python
quote = fetcher.get_quote(code)
bars = fetcher.get_kline(code, 220)
fetcher.disconnect()

if not quote or not bars:
    return {'error': f'Unable to obtain data for {code}'}

factors = compute_all_factors(
    quote['price'], quote['last_close'],
    quote['volume'], quote.get('b_vol', 0), quote.get('s_vol', 0),
    bars,
)
recommendation = generate_recommendation(factors, quote)

data_source = 'live' if fetcher.api is not None else 'simulated'

Technical Analysis

RealtimeFetcher.disconnect() always assigns None to fetcher.api. The data-source decision occurs only after that method is called, so fetcher.api is not None is always false at the provenance check. As a result, analysis based on successfully retrieved live data is incorrectly labeled as simulated.

This is an integrity and reliability defect rather than a direct privilege-escalation vulnerability. It can still affect security-sensitive decision-making because users are instructed to distinguish live market data from test data before relying on the generated financial analysis.

Attack Path

  1. The fetcher successfully connects to a configured TDX server.
  2. Live quote and historical bar data are retrieved.
  3. fetcher.disconnect() clears fetcher.api.
  4. The subsequent source check observes fetcher.api as None.
  5. The report labels the live-data analysis as simulated, preventing reliable verification of its actual provenance.

No external attacker is required to trigger this behavior; it occurs during the normal successful live-data workflow.

Impact Assessment

The defect does not grant additional system privileges or expose confidential information. Its scope is limited to incorrect provenance metadata in single-stock a ...[truncated 194 chars]

Remediation
View remediation

Remediation Suggestions

  • Record whether live retrieval succeeded before disconnecting:
    python
    quote = fetcher.get_quote(code)
    bars = fetcher.get_kline(code, 220)
    used_live_data = fetcher.api is not None
    fetcher.disconnect()
    
    data_source = 'live' if used_live_data else 'simulated'
    
  • Prefer returning explicit provenance metadata from get_quote() and get_kline() rather than inferring provenance from connection state.
  • Track quote and bar provenance separately because one operation may use live data while another falls back to simulation.
  • Add tests for successful live retrieval, complete simulation, and partial fallback behavior.
  • Clearly expose mixed-source results and avoid presenting them as wholly live or wholly simulated.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (14)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The documented purpose understates important behavior: the skill can batch-scan a stock pool and can fall back to simulated data while still producing actionable buy recommendations. This mismatch is dangerous because users or downstream agents may treat outputs as real, single-stock analysis when they may instead be broad screening results or recommendations derived from fake data, increasing the risk of unsafe financial guidance.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding

The skill documents executable behavior that reads local files (for example, references and script paths) but does not declare any tool scope or permissions boundary. In an agent environment, missing explicit tool restrictions increases the chance the skill can access local content more broadly than intended and makes security review and runtime enforcement harder.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The trigger description is broad enough to match many ordinary stock-related questions, which can cause the skill to activate when the user did not specifically request this model or recommendation style. In a financial context, unintended activation is risky because it may inject deterministic buy/sell framing into general informational conversations and lead users to over-rely on a niche scoring system.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest description is entirely framed in Chinese and presents the skill behavior as producing purchase recommendations for A-share analysis without indicating that language can be adapted to user preference. This can violate a language/locale policy when a skill implicitly fixes output language rather than offering a choice.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The usage section repeats broad activation guidance without defining clear limits on when the skill should not be used, such as missing data, unsupported markets, or requests for non-recommendation information. This increases the chance of over-application and misleading output, especially because the skill produces explicit purchase recommendations in a sensitive financial domain.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The document provides explicit, actionable investment recommendations such as '强烈推荐买入' and '建议买入' with confidence levels and trading guidance, while later stating the system 'does not constitute investment advice.' This contradiction can mislead users into treating the output as regulated or trustworthy financial advice without appropriate disclosures, suitability checks, or compliance controls.

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 presents user-facing report content, warnings, headings, help text, and recommendations entirely in Chinese, including the CLI description and generated output. Under the stated policy, forcing a specific language without offering user choice or documenting a justified locale constraint is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest says the skill gives explicit purchase advice in four categories: '强烈推荐买入/建议买入/观望/不建议买入'. However, the signal_for_score function maps scores to different labels ('强势买入/关注/留意/回避'), creating an intent/documentation mismatch for a user-facing output the skill claims to standardize.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill's natural-language signals and recommendations are hard-coded in Chinese, including labels such as '强势买入', '关注', and '回避'. There is no indication that the user can choose language or locale, so the file imposes a specific language by default.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The recommendation engine returns all verdicts, actions, reasons, and risks in Chinese, such as '强烈推荐买入' and '不建议买入'. Because no language-selection mechanism is provided, this constitutes a locale/language policy issue rather than a domain-specific requirement that is documented and justified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill automatically initiates outbound network connections to configured market data servers when live mode is enabled, without any user-facing disclosure or explicit consent. In an agent skill context, silent external requests can leak usage metadata, enable unexpected network access, and violate sandbox or privacy expectations even if the destination is a legitimate market-data service.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

This JSON file contains user-visible server name values such as "主站1" through "主站4", which force a specific language presentation. Under the policy, hard-coded locale-specific language without user opt-in or documented justification can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The title and all substantive guidance in the file are presented only in Chinese, with no indication that users may choose another language or locale. 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.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The docstring describes a full factor report plus buy recommendation, which implies consistency with the manifest’s recommendation scheme. In practice, the returned 'factors' payload embeds 'signal' values from a separate label set ('强势买入/关注/留意/回避'), which diverges from the documented recommendation categories and can contradict the advertised intent.

Content

No source excerpt is available for this finding.