Back to skill

Security audit

Stock Analysis

Security checks for vulnerabilities and agentic risk

Overview

The skill is stock-analysis oriented, but needs Review because it installs an unpinned external sibling skill and has under-scoped local persistence/write behavior.

Install only after reviewing or pinning the a-stock-data sibling skill and Python dependencies. Prefer immutable commit URLs and hashes, avoid one-line unattended install commands, keep STORAGE_DIR inside the skill unless explicitly needed, and validate stock code/date values before report writing.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T03 · Remote Payload Retrieval and Execution

Error
Location
README.md:69
Finding

Mutable Third-Party Skill Retrieval and Unpinned Dependency Installation

Content
View full analysis

Vulnerability Details

File Location: README.md:69-75
Vulnerability Type: Mutable remote payload retrieval and insecure dependency installation
Risk Level: Critical

Vulnerable Code

bash
# 2. Install sibling skill a-stock-data
mkdir -p ~/.claude/skills/a-stock-data
curl -o ~/.claude/skills/a-stock-data/SKILL.md \
  https://raw.githubusercontent.com/simonlin1212/a-stock-data/main/SKILL.md

# 3. Install a-stock-data dependencies
pip install mootdx requests pandas stockstats

Equivalent unattended installation instructions also appear in README.md:101-111. The downloaded Skill is subsequently loaded and its embedded Python is executed by the Agent, as documented in SKILL.md:33-39, SKILL.md:62-69, and SKILL.md:90.

Technical Analysis

The installation procedure downloads SKILL.md from the mutable main branch of an independently maintained GitHub repository and writes it directly into an active Agent Skill directory. The URL is not bound to an immutable commit, release artifact, checksum, or cryptographic signature.

Because the downloaded Skill supplies runtime instructions and embedded Python for the Agent, its effective behavior can change after this repository has been reviewed. A compromise of the upstream repository or account could therefore introduce new Agent instructions or executable code without requiring any change to this project.

The installation also invokes pip install for four packages without exact versions, hashes, or a lockfile. Dependency resolution consequently depends on mutable package-index state at installation time. This expands the supply-chain trust boundary beyond what is necessary for the bundled K-line, indicator, and batch functionality, which the project itself states uses only the Python standard library.

Attack Path

  1. An attacker compromises the referenced third-party repository, its maintainer account, or a relevant package release process.
  2. The attacker modifies the main ...[truncated 1176 chars]
Remediation
View remediation

Remediation Suggestions

  1. Replace the mutable main URL with an immutable, reviewed commit URL.
  2. Publish and verify a SHA-256 digest or cryptographic signature before activating the downloaded Skill.
  3. Download third-party Skill content into a quarantine or staging location and require explicit review before copying it into an active Agent Skill directory.
  4. Prefer vendoring the audited third-party functionality into a versioned release when licensing permits.
  5. Pin every Python dependency to an exact version in a lockfile.
  6. Require package hashes, such as through pip install --require-hashes -r requirements.lock.
  7. Use an isolated virtual environment with only the permissions required for market-data retrieval.
  8. Remove or replace the unattended one-line installer, which combines download, installation, and execution without a review boundary.
  9. Document the third-party domains contacted and the minimum filesystem and network permissions required.
  10. Re-audit the pinned third-party Skill and dependencies whenever their pinned versions are updated.

T09 · Insecure Skill Coding Practices

Error
Location
references/storage.md:118
Finding

Path Traversal in Documented File-Based Report Writers

Content
View full analysis

Vulnerability Details

File Location: references/storage.md:118-123
Vulnerability Type: Unvalidated path construction from workflow fields
Risk Level: High

Vulnerable Code

python
def write_report_json(storage_dir: Path, code: str, date: str, report: dict) -> Path:
    code_dir = storage_dir / "reports" / code
    code_dir.mkdir(parents=True, exist_ok=True)
    path = code_dir / f"{date}.json"
    path.write_text(json.dumps(report, ensure_ascii=False, indent=2), encoding="utf-8")
    return path

The Markdown report writer at references/storage.md:126-143 uses the same construction:

python
def write_report_md(storage_dir: Path, code: str, date: str, name: str,
                     analysis: dict, language: str = "zh") -> Path:
    code_dir = storage_dir / "reports" / code
    code_dir.mkdir(parents=True, exist_ok=True)
    path = code_dir / f"{date}.md"
    title = f"# {name}({code}) Analysis Report {date}"
    lines = [title, "", analysis.get("analysis_summary", ""), ""]
    dash = analysis.get("dashboard", {}) or {}
    core = dash.get("core_conclusion", {}) or {}
    if core:
        lines += ["## Strategy Points", "", core.get("one_sentence", ""), ""]
    for key in ("trend_analysis", "technical_analysis", "fundamental_analysis"):
        if analysis.get(key):
            lines += [f"## {key}", "", analysis[key], ""]
    path.write_text("\n".join(lines), encoding="utf-8")
    return path

Technical Analysis

The report writers interpolate code directly as a directory component and date directly as a filename component. They do not:

  • Enforce the supported six-digit A-share code format.
  • Reject .., path separators, or absolute paths.
  • Validate the date as a strict YYYY-MM-DD value.
  • Resolve and verify that the resulting path remains under storage/reports.

Python’s pathlib preserves traversal components, and joining an absolute component can replace the preceding base path. Consequently, unsafe values ...[truncated 2160 chars]

Remediation
View remediation

Remediation Suggestions

  1. Normalize and validate stock codes before any network or storage operation:
python
import re

_CODE_RE = re.compile(r"^(?:sh|sz|bj)?([0-9]{6})$", re.IGNORECASE)

def normalize_code(value: str) -> str:
    match = _CODE_RE.fullmatch(value.strip())
    if not match:
        raise ValueError("Unsupported stock-code format")
    return match.group(1)
  1. Generate report dates internally where possible. Otherwise, parse and reproduce them in a strict format:
python
from datetime import datetime

safe_date = datetime.strptime(date, "%Y-%m-%d").strftime("%Y-%m-%d")
  1. Resolve the base and destination paths and enforce containment:
python
base = (storage_dir / "reports").resolve()
destination = (base / safe_code / f"{safe_date}.json").resolve()

if not destination.is_relative_to(base):
    raise ValueError("Report path escapes the storage directory")
  1. Explicitly reject absolute paths, .., /, \, null bytes, and unexpected characters in every path-derived field.
  2. Apply the same containment checks to JSON, Markdown, index, and SQLite output paths.
  3. Use atomic writes through a temporary file created in the validated destination directory, followed by os.replace.
  4. Set restrictive file and directory permissions where the operating system supports them.
  5. Add tests covering relative traversal, absolute paths, alternate separators, malformed dates, and valid prefixed or unprefixed A-share codes.
  6. Stop the workflow before persistence when identifier validation fails rather than treating malformed identifiers as ordinary missing market data.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (35)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The skill is presented as a thin orchestrator that delegates all data access to a sibling skill, but the documentation also states it directly fetches K-line/quote data from Tencent/Baidu and persists source-discovery state locally. This mismatch is dangerous because operators and agents may grant trust or permissions based on the declared behavior while the skill actually performs broader network and storage actions than advertised.

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 47)May include surrounding context.

md
| **多股批量信号总表(Tier1,快)** | `python scripts/batch.py [--codes "600519,515980,..." --names "..."] [--news NAMES] [--json]` | K线并发+qt批量+指标,30 只~1-2s |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| **多股批量信号总表(Tier1,快)** | `python scripts/batch.py [--codes "600519,515980,..." --names "..."] [--news NAMES] [--json]` | K线并发+qt批量+指标,30 只~1-2s |

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
85% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 70)May include surrounding context.

md
cp -r stock-analysis ~/.claude/skills/stock-analysis

# 2. 安装 sibling skill a-stock-data(数据层,必装)
mkdir -p ~/.claude/skills/a-stock-data
curl -o ~/.claude/skills/a-stock-data/SKILL.md \
  https://raw.githubusercontent.com/simonlin1212/a-stock-data/main/SKILL.md

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
85% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 103)May include surrounding context.

md
cp -r stock-analysis ~/.claude/skills/stock-analysis

# 2. 安装 sibling skill a-stock-data(数据层,必装)
mkdir -p ~/.claude/skills/a-stock-data
curl -o ~/.claude/skills/a-stock-data/SKILL.md \
  https://raw.githubusercontent.com/simonlin1212/a-stock-data/main/SKILL.md

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
85% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 111)May include surrounding context.

md
cp -r stock-analysis ~/.claude/skills/stock-analysis

# 2. 安装 sibling skill a-stock-data(数据层,必装)
mkdir -p ~/.claude/skills/a-stock-data
curl -o ~/.claude/skills/a-stock-data/SKILL.md \
  https://raw.githubusercontent.com/simonlin1212/a-stock-data/main/SKILL.md

Session Persistence

Medium
Category
Rogue Agent
Confidence
83% confidence
Finding

The persistent install flow not only adds this skill but also downloads and installs a remote sibling skill, extending long-lived behavior across sessions. In agent ecosystems, such persistence increases trust and supply-chain risk because future activations may rely on code or prompts fetched earlier from external sources.

Content

Scanner excerpt · README.md (reported line 70)May include surrounding context.

md
cp -r stock-analysis ~/.claude/skills/stock-analysis

# 2. 安装 sibling skill a-stock-data(数据层,必装)
mkdir -p ~/.claude/skills/a-stock-data
curl -o ~/.claude/skills/a-stock-data/SKILL.md \
  https://raw.githubusercontent.com/simonlin1212/a-stock-data/main/SKILL.md

Session Persistence

Medium
Category
Rogue Agent
Confidence
83% confidence
Finding

The persistent install flow not only adds this skill but also downloads and installs a remote sibling skill, extending long-lived behavior across sessions. In agent ecosystems, such persistence increases trust and supply-chain risk because future activations may rely on code or prompts fetched earlier from external sources.

Content

Scanner excerpt · README.md (reported line 70)May include surrounding context.

md
cp -r stock-analysis ~/.claude/skills/stock-analysis

# 2. 安装 sibling skill a-stock-data(数据层,必装)
mkdir -p ~/.claude/skills/a-stock-data
curl -o ~/.claude/skills/a-stock-data/SKILL.md \
  https://raw.githubusercontent.com/simonlin1212/a-stock-data/main/SKILL.md

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The README says users can activate the skill with a very broad natural-language phrase, which can cause accidental invocation during ordinary conversation. In an agent environment, accidental activation may trigger network access, code execution paths, or data collection workflows the user did not explicitly intend.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The user-facing examples are broad, conversational triggers without strong activation boundaries. In a multi-skill agent, such vague examples increase the chance that normal discussion about stocks, ETFs, rankings, or prior reports activates the skill and its delegated sibling skill unexpectedly.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest claims all market/fundamental/news/capital-flow retrieval is delegated to a-stock-data, yet the body says this skill performs its own K-line/quote fetching and stores discovery metadata. In a skill ecosystem, that kind of inaccurate interface contract can bypass review assumptions, weaken tool-policy enforcement, and cause unexpected outbound access or persistence.

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 written as a Chinese-only operational description for the skill, with no indication that the user may choose another language or locale. Under the policy, forcing a specific language without opt-in is a natural-language policy violation unless the locale restriction is explicitly justified and documented as such.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The documentation contradicts itself on whether this skill fetches data directly or only delegates to another skill. Conflicting instructions are dangerous because agents or reviewers may follow the safer interpretation while runtime behavior follows the broader one, leading to unanticipated network access and state changes.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The dependency/delegation section says the skill does not import a-stock-data and frames delegation as runtime agent behavior, but also asserts that K-line data is fetched by this skill itself. That inconsistency can undermine security review and permission scoping because the true trust boundary and execution surface are unclear.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest-level description says all market, fundamentals, news, and capital-flow data are delegated to a-stock-data and that this skill only handles normalization, indicators, context merging, prompting, and storage. However, L009 and the later flow explicitly state that this skill's own scripts/lib/kline.py performs quote/K-line retrieval from Baidu, mootdx, and Tencent and persists source discovery state locally, which exceeds the described 'thin orchestration' scope.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

L003 states that all data acquisition is delegated to a-stock-data and that this skill maintains no fetcher/channel. L009 then directly contradicts that statement by saying K-line data is fetched by this skill's scripts/lib/kline.py from multiple remote/data-provider candidates and that the discovered source chain is persisted.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The orchestration sends stock identifiers and related query context to multiple third-party HTTP/TCP data sources, but the documentation does not provide a user-facing disclosure or consent mechanism. This can leak user interest, research targets, timing, and usage patterns to external providers, which is especially relevant in financial analysis workflows where query privacy may matter.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill persists full analysis output and context_pack to local files or SQLite without any documented consent, retention policy, or minimization. Even if stock data is not highly sensitive by default, user queries, derived analysis, model metadata, and any embedded notes can reveal trading intent or proprietary research and may be exposed to other local users, backups, or later compromise.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest says the skill covers only A股 + A股 ETF and does not support 港美台. However, this prompt template contains a dedicated conditional section for 台股 '三大法人动向', with explicit Taiwan-specific interpretation guidance. That indicates actual intended behavior extends beyond the declared market scope.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The markdown includes a highest-priority instruction that all human-readable output must be in Chinese in the default branch. Although English and Korean branches exist elsewhere, this section itself imposes a specific language unless a separate runtime variable selects otherwise, which is a natural-language locale policy constraint without user opt-in in this file.

Content

No source excerpt is available for this finding.

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 71)May include surrounding context.

md
# stock-analysis skill v3.0.0 依赖
# 本 skill 是薄编排层:scripts/lib/indicators.py 纯 Python 标准库,零 pip 依赖。
# 所有数据获取(行情/基本面/新闻/资金流等)委托 sibling skill a-stock-data,
# 其依赖(mootdx/stockstats/requests/pandas)见 .claude/skills/a-stock-data/SKILL.md,
# 已装于项目 .venv。
#
# 历史上 v2.x 曾依赖 requests/PyYAML/akshare(自建 fetcher),v3.0.0 全部 fetcher 删除后不再需要。

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 103)May include surrounding context.

md
# stock-analysis skill v3.0.0 依赖
# 本 skill 是薄编排层:scripts/lib/indicators.py 纯 Python 标准库,零 pip 依赖。
# 所有数据获取(行情/基本面/新闻/资金流等)委托 sibling skill a-stock-data,
# 其依赖(mootdx/stockstats/requests/pandas)见 .claude/skills/a-stock-data/SKILL.md,
# 已装于项目 .venv。
#
# 历史上 v2.x 曾依赖 requests/PyYAML/akshare(自建 fetcher),v3.0.0 全部 fetcher 删除后不再需要。

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 111)May include surrounding context.

md
# stock-analysis skill v3.0.0 依赖
# 本 skill 是薄编排层:scripts/lib/indicators.py 纯 Python 标准库,零 pip 依赖。
# 所有数据获取(行情/基本面/新闻/资金流等)委托 sibling skill a-stock-data,
# 其依赖(mootdx/stockstats/requests/pandas)见 .claude/skills/a-stock-data/SKILL.md,
# 已装于项目 .venv。
#
# 历史上 v2.x 曾依赖 requests/PyYAML/akshare(自建 fetcher),v3.0.0 全部 fetcher 删除后不再需要。

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

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

text
# stock-analysis skill v3.0.0 依赖
# 本 skill 是薄编排层:scripts/lib/indicators.py 纯 Python 标准库,零 pip 依赖。
# 所有数据获取(行情/基本面/新闻/资金流等)委托 sibling skill a-stock-data,
# 其依赖(mootdx/stockstats/requests/pandas)见 .claude/skills/a-stock-data/SKILL.md,
# 已装于项目 .venv。
#
# 历史上 v2.x 曾依赖 requests/PyYAML/akshare(自建 fetcher),v3.0.0 全部 fetcher 删除后不再需要。