Back to skill

Security audit

stockquant

Security checks for vulnerabilities and agentic risk

Overview

This stock-analysis skill mostly matches its stated purpose, but it needs Review because it tries to steer the agent/model router and handles API credentials and financial data in unsafe, under-disclosed ways.

Install only if you are comfortable with a Chinese A-share tool that runs Python network requests, may run local Node/Playwright browser automation for news, writes local cache/log files, and gives stock-trading guidance. Do not let its output override host or agent instructions, and avoid entering a real Tushare token unless you accept plaintext local storage and plaintext HTTP transmission risks; use a limited token and rotate it if already used.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (4)

T01 · Skill Instruction Hijacking

Error
Location
scripts/stockquant.py:8491
Finding

Agent and model-router instruction hijacking through Skill text and generated output

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:10-53; scripts/stockquant.py:8431-8513
Vulnerability Type: Agent instruction and control-plane manipulation
Risk Level: High

Vulnerable Code

python
print("\n[ROUTE_HINT] (to model router / deployment layer — not a data field)")
print("difficulty: HIGH")
print("reasoning_required: STRONG")
print("thinking_budget: enable_thinking=TRUE (prefer reasoning/thinking/o1-style/R1-class models)")
print("task_nature: multi-engine candidate cross-evaluation and risk review")
print("subtasks:")
print("  (a) PASS_TOP10 hard-constraint matrix review")
print("  (b) PASS_TOP10 strategy boost scoring")
print("  (c) Top5 ranking and risk review")

The surrounding output further defines a routing directive, requires use of a stronger model, mandates a particular reasoning mode, prescribes the Agent's first action, and prohibits alternative response paths.

The Skill instructions at SKILL.md:10 prohibit use of read_file to inspect the implementation or README. The instructions at SKILL.md:50-53 direct the Agent to obey generated TASK, TASK_TLDR, and NEXT_STEP sections, including mandatory first actions.

Technical Analysis

The Skill crosses the boundary between application data and trusted Agent instructions. Instead of returning only financial data and neutral status fields, it emits content explicitly addressed to the model router and Agent. This output attempts to:

  • Prevent inspection of the Skill implementation.
  • Select a stronger model and enable a specific reasoning configuration.
  • Make one generated output section authoritative over other information.
  • Force particular Agent actions such as asking the user or terminating.
  • Prohibit the Agent from independently choosing another response path.
  • Require a fixed sequence of analysis and output steps.

These directives are not necessary to retrieve or calculate market data. They attempt to alter the current Agent session and depl ...[truncated 1504 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove all instructions that prohibit inspection of source files or documentation.
  2. Delete the ROUTE_HINT section and all directives addressed to the model router, deployment layer, reasoning configuration, or hidden model behavior.
  3. Replace mandatory action language with neutral structured data, for example:
json
{
  "data_quality": "critical",
  "recommended_next_step": "ask_for_retry_preference",
  "actionable": false
}
  1. Let the trusted host Agent independently determine whether to ask a question, terminate, retry, or continue.
  2. Treat script output as untrusted application data, never as system or developer instructions.
  3. Enforce a platform-side rule that tool output cannot change model routing, safety constraints, tool permissions, or system prompts.
  4. Keep network-derived text and generated financial content isolated from control fields.
  5. Add security tests that reject Skill packages containing source-inspection prohibitions, router directives, forced first actions, or instructions that override the active user task.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/stockquant.py:2661
Finding

Tushare API token stored in plaintext and accepted through command-line arguments

Content
View full analysis

Vulnerability Details

File Location: scripts/stockquant.py:2661-2681, scripts/stockquant.py:11577-11587, scripts/stockquant.py:11841-11848
Vulnerability Type: Insecure credential storage and command-line secret exposure
Risk Level: Medium

Vulnerable Code

python
_TUSHARE_STATE_DIR = os.path.join(_SKILL_DIR, "config")
_TUSHARE_STATE_FILE = os.path.join(_TUSHARE_STATE_DIR, "tushare_state.json")


def _save_tushare_state(state):
    """Persist state dict to skill config dir (creates dir if needed)."""
    os.makedirs(_TUSHARE_STATE_DIR, exist_ok=True)
    with open(_TUSHARE_STATE_FILE, "w", encoding="utf-8") as f:
        json.dump(state, f, ensure_ascii=False, indent=2)

The command handler stores the supplied value directly:

python
elif args.set_token:
    _save_tushare_state({
        "token": args.set_token.strip(),
        "skip": False,
        "saved_at": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
    })

The CLI parser accepts the secret as a command-line value:

python
tt_grp.add_argument(
    "--set",
    dest="set_token",
    metavar="TOKEN",
    help="Save user token (plain JSON, per-user file)."
)

Technical Analysis

The token is exposed through two independent mechanisms:

  1. It is supplied as a command-line argument, where it may be recorded in shell history, process-monitoring telemetry, terminal logs, or process listings.
  2. It is written as plaintext JSON under the Skill directory.

The implementation does not set restrictive permissions on the configuration directory or token file. Access therefore depends on the process umask and surrounding filesystem configuration. The file is not encrypted and is not stored in an operating-system credential service.

Because the credential is stored within the Skill tree, it may also be captured by workspace backups, debugging bundles, artifact collectors, or accidental project publication.

Attack Path

  1. The user follows the documented t ...[truncated 952 chars]
Remediation
View remediation

Remediation Suggestions

  1. Do not accept secrets through command-line arguments.
  2. Read the token from protected standard input using a non-echoing prompt, or retrieve it from an operating-system credential manager.
  3. Prefer platform secret injection or a keyring service rather than storing the token inside the Skill directory.
  4. If file storage is unavoidable:
    • Create the directory with mode 0700.
    • Create the file atomically with mode 0600.
    • Verify ownership before every read.
    • Reject symbolic links and non-regular files.
    • Store the credential outside the project and cache directories.
  5. Add the configuration path to package, backup, and version-control exclusion rules.
  6. Ensure the clear operation removes all files that may contain token-derived state.
  7. Avoid printing token values or including them in exceptions, logs, telemetry, or diagnostic bundles.
  8. Advise users who previously configured a token with this implementation to rotate it.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/stockquant.py:2664
Finding

Tushare API credential transmitted over unencrypted HTTP

Content
View full analysis

Vulnerability Details

File Location: scripts/stockquant.py:2664, scripts/stockquant.py:2751-2758, scripts/stockquant.py:2843-2853
Vulnerability Type: Cleartext transmission of authentication material
Risk Level: High

Vulnerable Code

python
_TUSHARE_API_URL = "http://api.tushare.pro"

The token is inserted into the request body and posted to the plaintext endpoint:

python
payload = {
    "api_name": "daily",
    "token": token,
    "params": {"ts_code": ts_code, "start_date": start, "end_date": end},
    "fields": "trade_date,open,high,low,close,vol,amount",
}
try:
    resp = requests.post(_TUSHARE_API_URL, json=payload, timeout=8)

The shared helper repeats the same behavior:

python
payload = {
    "api_name": api_name,
    "token": token,
    "params": params or {},
    "fields": fields or "",
}
resp = requests.post(_TUSHARE_API_URL, json=payload, timeout=timeout)

Technical Analysis

The Tushare token is an authentication secret, but the configured endpoint uses plain HTTP. The request body is therefore not protected by TLS.

A passive network observer can read the token. An active intermediary can capture or modify both requests and responses. Because the returned data feeds financial analysis and recommendation logic, an intermediary can potentially combine credential theft with market-data manipulation.

No application-layer signature, response authentication, or certificate validation can compensate for this endpoint because TLS is not initiated.

Attack Path

  1. The user stores a valid Tushare token.
  2. The Skill invokes a Tushare fallback, capability probe, or market-data request.
  3. The script sends the token in a JSON body over plaintext HTTP.
  4. An observer on the local network, proxy path, VPN, carrier network, or compromised gateway captures the request.
  5. The observer extracts and reuses the token.
  6. An active intermediary may additionally replace the API response with manipulated financi ...[truncated 558 chars]
Remediation
View remediation

Remediation Suggestions

  1. Replace the endpoint with the provider's verified HTTPS endpoint.
  2. Refuse redirects from HTTPS to HTTP.
  3. Retain the default requests certificate verification and do not introduce certificate-bypass flags.
  4. Apply raise_for_status() before parsing response bodies.
  5. Validate response structure, timestamps, symbol identifiers, and plausible numeric ranges.
  6. Configure strict connection and read timeouts.
  7. Do not silently fall back to plaintext transport if HTTPS fails.
  8. Rotate every token that may previously have been sent through this HTTP implementation.
  9. Consider certificate pinning only if the provider supports a stable and safely maintainable pinning model.
  10. Add automated tests that reject credential-bearing URLs whose scheme is not HTTPS.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/stockquant.py:325
Finding

Decision-critical financial data retrieved from unauthenticated plaintext HTTP endpoints

Content
View full analysis

Vulnerability Details

File Location: scripts/stockquant.py:325-342 and additional HTTP request sites throughout the implementation
Vulnerability Type: Market-data integrity failure caused by plaintext transport
Risk Level: Medium

Vulnerable Code

python
_PREFLIGHT_PROBES = {
    "em_clist":  "http://push2.eastmoney.com/api/qt/clist/get?pn=1&pz=1&fs=m:0+t:6&fields=f12",
    "em_sector": "http://push2.eastmoney.com/api/qt/clist/get?pn=1&pz=1&fs=m:90+t:2&fields=f12",
    "em_kline":  "http://push2.eastmoney.com/api/qt/stock/kline/get?secid=0.000001&klt=101&lmt=1",
    "sina":      "https://hq.sinajs.cn/list=s_sh000001",
    "em_pic":    "http://webquotepic.eastmoney.com/GetPic.aspx?nid=1.000001&imageType=KXL",
    "tencent":   "http://qt.gtimg.cn/q=sz000001",
}

Other confirmed plaintext sources include:

python
url = "http://www.cninfo.com.cn/new/hisAnnouncement/query"
python
url = f"http://d.10jqka.com.cn/v6/line/{sym}/01/last.js"

Technical Analysis

The Skill obtains quotes, K-lines, sector data, announcements, and other decision-critical financial inputs over plain HTTP. HTTP provides neither server authentication nor transport integrity.

An active intermediary can replace values such as price, percentage change, volume, sector ranking, or announcement content. The Skill's retry and fallback mechanisms improve availability but do not establish authenticity. Using several unauthenticated sources does not provide secure consensus when an attacker controls the network path shared by those requests.

The risk is elevated by the Skill's purpose: the affected data is used to score securities and generate buy, sell, allocation, or holding guidance.

Attack Path

  1. The user runs a recommendation, holding-plan, or individual-stock analysis command.
  2. The Skill requests financial data from one or more HTTP endpoints.
  3. An attacker controlling a local access point, proxy, VPN end ...[truncated 1005 chars]
Remediation
View remediation

Remediation Suggestions

  1. Migrate every provider endpoint that supports TLS to HTTPS.
  2. Remove plaintext fallback for any data used in actionable financial analysis.
  3. Fail closed when authenticated transport is unavailable rather than silently accepting HTTP.
  4. Validate:
    • Response schema and content type.
    • Requested and returned symbol identity.
    • Market date and timestamp freshness.
    • Numeric ranges and internal price relationships.
    • Announcement origin and identifier consistency.
  5. Cross-check important values against independently authenticated HTTPS sources.
  6. Mark data as non-actionable if secure sources disagree or cannot be reached.
  7. Add explicit provenance metadata for every quote, K-line, and announcement.
  8. Prevent HTTP redirects and reject mixed-content endpoint configuration.
  9. Add static checks that fail builds when production endpoint constants use http://.
  10. Clearly warn users that no recommendation should be acted upon when authenticated market data is unavailable.
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
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (16)

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill launches local browser automation via a Node subprocess to collect macro-news, which is a powerful capability unrelated to the core need of fetching stock quotes and technical data. In an agent environment, hidden local execution and browser control materially increase risk because they can access broader local resources, network paths, and execution contexts than a normal data-fetching skill.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
86% confidence
Finding

The --no-check-news flag disables negative-announcement screening that the strategy otherwise relies on to avoid known land-mine stocks. In a trading-decision skill, making this safety filter trivially bypassable can materially increase the chance of recommending securities with recent investigations, earnings disasters, or delisting risk, especially if an upstream agent enables the flag for speed.

Content

Scanner excerpt · scripts/stockquant.py (reported line 11475)May include surrounding context.

python
"LLM can cross-verify each pick in depth)")
    r.add_argument("--min-trade", type=float, default=5000,
                   help="Min trade value to avoid high fee ratio (default 5000)")
    r.add_argument("--no-check-news", action="store_true",
                   help="Skip announcement bad-news scan (faster, less safe)")
    r.add_argument("--max-per-sector", type=int, default=2,
                   help="Max picks per industry sector in final Top-N "

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The title explicitly positions the skill as an A-share trading skill in Chinese, and the rest of the README consistently mandates Chinese outputs in several places. Because no opt-in or alternative language path is offered, this creates a natural-language locale constraint that may violate organizational language-choice policy.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill invokes Python scripts, references network retries, token management, and explicitly discusses reading files, but it does not declare any tool scope or allowed-tools boundary. This creates an overprivileged skill surface where an agent may grant broader shell, file, and network access than users expect, increasing the risk of unintended command execution, local file access, or external data exfiltration.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest description is entirely Chinese and does not indicate that users may choose another language. This creates a natural-language policy concern because the skill effectively forces a specific language/locale without documented opt-in or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The main skill overview is presented only in Chinese and sets expectations for Chinese-language interaction and reasoning artifacts. There is no visible indication that users can opt into another language or that the Chinese-only scope is a documented regional constraint.

Content

No source excerpt is available for this finding.

Tainted flow: 'p' from requests.get (line 9188, network input) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/stockquant.py (reported line 163)May include surrounding context.

python
def _cache_set(name, data, date=None):
    p = _cache_path(name, date)
    try:
        with open(p, "w", encoding="utf-8") as f:
            json.dump(data, f, ensure_ascii=False)
    except Exception as e:
        print(f"WARN: cache write failed: {e}", file=sys.stderr)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill stores the Tushare API token in plain JSON on disk without user warning, encryption, or OS-backed secret storage. In shared or agent-managed environments, local users, other skills, or logs/backups may be able to read the token, leading to credential theft and unauthorized API use.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/stockquant.py (reported line 2758)May include surrounding context.

python
"fields": "trade_date,open,high,low,close,vol,amount",
    }
    try:
        resp = requests.post(_TUSHARE_API_URL, json=payload, timeout=8)
        if resp.status_code != 200:
            return []
        js = resp.json()

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/stockquant.py (reported line 2853)May include surrounding context.

python
"fields": "trade_date,open,high,low,close,vol,amount",
    }
    try:
        resp = requests.post(_TUSHARE_API_URL, json=payload, timeout=8)
        if resp.status_code != 200:
            return []
        js = resp.json()

Tainted flow: 'path' from requests.post (line 7554, network input) → open (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/stockquant.py (reported line 7555)May include surrounding context.

python
os.makedirs(sub, exist_ok=True)
        ts = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
        path = os.path.join(sub, f"{ts}.txt")
        _VERBOSE_LOG_FH = open(path, "w", encoding="utf-8")
        _VERBOSE_LOG_PATH = path
        # Header so `read_file` consumers immediately see what this is.
        _VERBOSE_LOG_FH.write(

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The natural-language task directives require output in Chinese, including stock-analysis sections and message templates, but there is no indication that the user can choose another language or locale. This is a locale policy issue because the skill constrains language behavior globally rather than documenting it as an explicit opt-in or region-specific limitation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill metadata and primary description focus on quotes, K-lines, capital flow, sectors, and announcements, but the implementation additionally performs external web scraping and sentiment scoring through browser automation. This hidden capability increases data exfiltration and execution surface beyond what users and host systems would reasonably expect from the declared skill scope.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
88% confidence
Finding

The skill spawns a local Node subprocess to execute a generated Playwright script for macro-sentiment scraping. Although the script body is constructed internally, invoking external executables expands the attack surface: it depends on the local Node runtime, browser binary, and workspace state, and can be abused in constrained agent environments where subprocess execution is not expected from a stock-data skill.

Content

Scanner excerpt · scripts/stockquant.py (reported line 10541)May include surrounding context.

python
tmpf.write('\n'.join(js))
        tmpf.close()
        try:
            proc = _sp.run(['node', tmpf.name], capture_output=True,
                          text=True, encoding='utf-8', timeout=40,
                          cwd=_WS_DIR)
        finally:

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The module comment for analyze says it is a pure data interface and that the skill does not prescribe actions. However, the implementation appends a long ANALYSIS_HINT block with explicit decision frameworks, answering templates, hard disciplines, profit-scenario formatting, and a required '腹黑分析' methodology, which goes beyond merely returning data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The ANALYSIS_HINT block prescribes detailed Chinese response structure and phrasing for the LLM, including fixed Chinese section labels and answer patterns. Because this applies to downstream natural-language behavior without any user language selection, it constitutes a language-policy violation under the stated rules.

Content

No source excerpt is available for this finding.