Back to skill

Security audit

TuShare Stock Skill

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed Tushare stock-research skill that uses a user-provided Tushare token for market-data queries, with some non-blocking hardening issues around dependencies, cache storage, and slightly broad catalog scope.

Install this only in a virtual environment, provide a Tushare token through TUSHARE_TOKEN when possible, and avoid using TUSHARE_STOCK_ENV_FILE unless it points to a minimal file containing only that token. Be aware that direct fetches can reach some adjacent non-A-share or cross-market Tushare catalog entries, and consider setting TUSHARE_STOCK_CACHE_DIR to a private per-user cache directory.

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)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/tushare_stock.py:23
Finding

Predictable and Symlink-Unsafe Shared Cache Path

Content
View full analysis
Path: CACHE_DIR.mkdir(parents=True, exist_ok=True) return CACHE_DIR / name def load_stock_cache() -> list[dict] | None: path = cache_path("stock_basic_cache.json") if not path.exists(): return None age = time_since(path) if age > timedelta(hours=24): return None return json.loads(path.read_text(encoding="utf-8")) ``` ```python if not frames: return [] merged = pd.concat(frames, ignore_index=True).drop_duplicates(subset=["ts_code"]) merged = merged.fillna("") rows = merged.to_dict(orient="records") cache_path("stock_basic_cache.json").write_text(json.dumps(rows, ensure_ascii=False), encoding="utf-8") return rows ``` ### Technical Analysis The default cache directory is a predictable, shared path under `/tmp`. The implementation creates the directory with `exist_ok=True` but does not verify: - Whether the directory is owned by the current user. - Whether the directory or cache file is a symbolic link. - Whether the cache file is a regular file. - Whether directory and file permissions prevent access by other local users. - Whether the final write is atomic. Both `read_text()` and `write_text()` follow symbolic links. An attacker with local access could pre-create `/tmp/tushare_stock_skill`, place a crafted `stock_basic_cache.json` in it, or arrange a link to another path. The program would then trust the attacker-controlled cache when resolving stock names or follow the selected path during a cache write. The cached information is public stock metadata rather than credentials. Consequently, this issue does not directly expose ...[truncated 1583 chars]
Remediation
View remediation
None: CACHE_DIR.mkdir(mode=0o700, parents=True, exist_ok=True) stat = CACHE_DIR.lstat() if CACHE_DIR.is_symlink() or stat.st_uid != os.geteuid(): raise RuntimeError("Unsafe cache directory") def atomic_cache_write(path: Path, content: str) -> None: initialize_cache_dir() fd, temporary_name = tempfile.mkstemp(dir=CACHE_DIR) try: os.fchmod(fd, 0o600) with os.fdopen(fd, "w", encoding="utf-8") as handle: handle.write(content) handle.flush() os.fsync(handle.fileno()) os.replace(temporary_name, path) finally: if os.path.exists(temporary_name): os.unlink(temporary_name) ``` ]]>

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Unpinned Third-Party Dependencies Permit Non-Reproducible Installation

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (34)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

声明描述的是一个面向A股使用场景的数据获取与分析型技能,听起来应当直接调用 Tushare 数据接口来获取股票数据,并进一步支持个股分析或交易观察。但给出的代码并未调用任何股票行情、财务或分析接口,也没有实现分析逻辑、观察逻辑或面向用户的查询功能。它做的事情是抓取 https://tushare.pro/document/2?doc_id=14 及其相关文档页面,解析接口说明、积分权限、参数表和返回字段,然后写出 references/stock_endpoints.json 和 stock_endpoints.md,属于“文档索引/元数据构建”脚本。虽然主题仍与 Tushare A 股接口相关,但主要用途与声明存在实质偏差,因此应判定为不匹配。

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 79)May include surrounding context.

md
python scripts/tushare_stock.py run --text "<请求内容>"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 127)May include surrounding context.

md
python scripts/tushare_stock.py run --text "<请求内容>"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 133)May include surrounding context.

md
python scripts/tushare_stock.py run --text "<请求内容>"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 139)May include surrounding context.

md
python scripts/tushare_stock.py run --text "<请求内容>"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 145)May include surrounding context.

md
python scripts/tushare_stock.py run --text "<请求内容>"

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The entire skill description, examples, and interface guidance are presented only in Chinese, and the skill is framed specifically as a Chinese A-share research assistant without any opt-in or alternative language support. Under the policy, forcing a specific language or locale without user choice is a natural-language policy concern unless the constraint is explicitly justified as region-specific compliance or similar.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill declares environment, file, and network capabilities in metadata but does not define an explicit tool scope such as allowed-tools or permissions. That weakens least-privilege boundaries and can cause an agent runtime to grant broader access than users expect, especially since the skill can read a token, write cache files, and make outbound requests. In this context the behavior is not overtly malicious, but the missing scope increases risk if the skill is invoked in a permissive environment.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The markdown states that user-facing output '默认使用简体中文' and further instructs the skill to ask follow-up questions in Chinese when requests are unclear. This imposes a specific language/locale by default and does not offer the user a language choice or opt-in.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Several endpoints in the catalog are specifically for 港股通, Hong Kong trading statistics, Hong Kong holdings, CCASS, and AH-share comparison, which are not limited to China A-shares. This is a semantic scope expansion relative to the manifest’s A-share-focused description.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest describes a Tushare skill for Chinese A-shares, stock data, individual-stock analysis, and trading observation. However, the catalog explicitly exposes generic market interfaces whose documented parameters allow assets beyond A-shares, including Hong Kong/US markets, digital currency, futures, options, funds, and convertible bonds, which materially broadens the skill’s operational scope.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

Using the generic alias '股票开户数据' on one endpoint while another endpoint also claims it creates ambiguous routing behavior. Ambiguity in skill invocation is dangerous in agent systems because the model may select deprecated, inactive, or semantically different tools without user awareness.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

A second endpoint claiming the same broad alias increases collision risk and makes routing nondeterministic. This is particularly risky here because one endpoint is marked inactive/legacy, so ambiguous invocation can return stale or unexpected data and undermine user trust in analytical output.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The generic alias '板块资金流向' lacks source or market constraints, making accidental or adversarial prompt steering more likely in NL-based routing. In a tool-using agent, ambiguous triggers can cause the wrong endpoint to fire and produce misleading analysis or unnecessary data access.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Overly broad aliases can cause unintended skill or endpoint invocation, especially in an agent setting where natural-language routing is automatic. That can lead the system to query the wrong market dataset or perform actions with higher-cost, broader-scope, or less appropriate endpoints than the user intended.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This code hardcodes user-facing labels in Chinese, and the pattern continues throughout the file in conclusions, summaries, and limitations. Because the skill does not offer language selection or document that it is intentionally limited to a Chinese-speaking context, it violates the stated language/locale policy requirement.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Status strings and payload keys are systematically converted to Chinese, and all emitted JSON uses that localized structure. This is a natural-language locale policy concern because the file imposes a single language on users without any opt-in, fallback, or configuration choice.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill accepts TUSHARE_STOCK_ENV_FILE and reads TUSHARE_TOKEN from an arbitrary local file path, enabling the process to read attacker-influenced files on disk if that environment variable is set unsafely by a caller or wrapper. In a skill environment, arbitrary local file reads exceed the stated stock-analysis purpose and can expose secrets or sensitive local configuration.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

Natural-language content throughout the manifest is presented exclusively in Chinese, including user-facing titles and aliases, with no indication that users may choose another language. If this skill is intended for a broader user base, that constitutes a locale/language constraint without documented opt-in or justification.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The entry is titled and named as a real-time ranking/list endpoint, and its output fields are ranking-style market snapshot fields across many stocks. Yet the description says it contains all intraday transaction records for a stock since market open, which describes tick-detail behavior instead of ranking behavior.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The stk_account and stk_account_old endpoints expose securities account-opening statistics, which are investor-account market structure data rather than stock-specific data retrieval, individual stock analysis, or trading observation. That capability is adjacent to market research but not clearly implied by the manifest’s narrower stock-oriented description.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

The dependency list leaves pandas unpinned, so installs are not reproducible and may unexpectedly pull a vulnerable or breaking release in different environments or at different times. In a data-analysis skill that relies on third-party packages, this increases supply-chain risk and makes it difficult to verify whether known advisories apply.

Content

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

text
pandas
tushare
requests
beautifulsoup4

Unverifiable Dependency: pandas has 1 known advisory(ies) (CVE-2020-13091 (** DISPUTED ** pandas through 1.0.3 can unserialize and execute commands from an)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
93% confidence
Finding

Pandas has at least one known advisory, and because no version is pinned, it is impossible to determine from this manifest whether the deployed version is affected. This uncertainty is itself a security weakness because vulnerable versions may be installed silently, especially across different machines or over time.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

The tushare dependency is unpinned, which means builds may resolve to different versions over time without review. For a finance-focused skill that consumes market data, inconsistent dependency resolution can introduce security, reliability, or integrity issues if a bad or compromised release is published.

Content

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

text
pandas
tushare
requests
beautifulsoup4

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
99% confidence
Finding

Requests is unpinned, so the environment may install an older vulnerable release or an unexpected newer release with security-impacting changes. Because this skill likely performs network access to retrieve stock data, the use of an unpinned HTTP client is somewhat more security-relevant than in a purely local tool.

Content

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

text
pandas
tushare
requests
beautifulsoup4

Static analysis

No suspicious patterns detected.