Back to skill

Security audit

A股金融数据整合技能

Security checks for vulnerabilities and agentic risk

Overview

The skill is mainly a financial-data guide, but it tells the agent to persistently edit its own instruction file after trial-and-error, which needs review before installation.

Install only if you are comfortable reviewing or removing the self-update instruction first. Keep the installed skill directory read-only during normal use, and treat the cache example as template code that needs stock-code/date/frequency validation before reuse.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • 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
  • 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 (2)

T02 · Agent Memory Poisoning

Warning
Location
SKILL.md:1120
Finding
Mandatory Persistent Self-Modification Can Poison Future Skill Behavior<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 1120–1123 **Vulnerability Type**: Persistent instruction poisoning through mandatory self-modification **Risk Level**: Medium ### Vulnerable Instruction The following is a faithful English rendering of the relevant instruction: ```markdown When you obtain a correct result only after multiple attempts—for example, after trial and error with parameter formats, changing interface selection, or discovering undocumented constraints—you must briefly append the experience to the pitfall records in Chapter 16. Recording standard: - Only record cases that succeeded after two or more attempts. ``` ### Technical Analysis The Skill requires the agent to append runtime observations to `SKILL.md`, which is persistent instruction state loaded by future sessions. This creates a write channel from runtime data into trusted Skill instructions. The instruction does not require: - Confirmation that the observed workaround is accurate. - Verification against authoritative documentation. - Sanitization of content originating from API responses or user input. - Human approval before modifying the Skill. - Separation of untrusted observations from executable agent instructions. - Provenance, integrity protection, or rollback support. If an external financial-data source, API response, or user-controlled workflow causes repeated failures and then presents a crafted workaround, the agent may treat that workaround as learned experience and persist it. Later sessions could trust the resulting text as part of the Skill. This is classified as memory poisoning rather than session-only instruction hijacking because the prescribed modification is intended to survive the current run and influence future sessions. ### Attack Path 1. The agent performs a financial-data query using the Skill. 2. An attacker-controlled or compromised data source causes the first two or more attempts to fail. 3. The source then retur ...[truncated 1375 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the mandatory requirement to edit `SKILL.md` during ordinary Skill execution. 2. Store runtime observations in a separate, non-instructional log that is not automatically loaded as trusted agent guidance. 3. Require explicit human approval before promoting an observation into Skill documentation. 4. Validate proposed changes against authoritative Baostock or Akshare documentation and independent test cases. 5. Record provenance for every proposed entry, including the source, timestamp, affected library version, and validation results. 6. Treat API responses and user-provided content as untrusted data and prohibit copying them directly into persistent instructions. 7. If automated updates are necessary, use a constrained schema, content validation, integrity checks, version control, and a reviewable pull-request workflow. 8. Ensure the installed Skill directory is read-only during normal execution and only writable by a separate, authorized maintenance process. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:766
Finding
Unsanitized Cache-Key Components Permit Path Traversal and Arbitrary CSV Writes<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 766–776 **Vulnerability Type**: Path traversal in a documented disk-cache implementation **Risk Level**: Medium ### Vulnerable Code ```python def get_cache_path(code, start_date, end_date, freq): os.makedirs(CACHE_DIR, exist_ok=True) return os.path.join(CACHE_DIR, f"{code}_{start_date}_{end_date}_{freq}.csv") def load_cache(path): if os.path.exists(path): return pd.read_csv(path, dtype=str) return None def save_cache(path, df): df.to_csv(path, index=False) ``` ### Technical Analysis The cache path is constructed by directly interpolating `code`, `start_date`, `end_date`, and `freq` into a filesystem path. The implementation does not validate these values, remove path separators, normalize the result, or confirm that the resolved destination remains under `CACHE_DIR`. If any interpolated value contains traversal sequences such as `../` or platform-specific path separators, the generated path can escape the intended `data_cache` directory. The resulting path is subsequently passed to `pandas.DataFrame.to_csv`, which writes to that location. Although the `.csv` suffix is fixed, this still permits creation or replacement of writable files whose final names end in `.csv`. The adjacent `load_cache` function also accepts an unrestricted path, although the demonstrated usage obtains that path from `get_cache_path`. The issue appears in a template rather than an executable project script. Exploitation therefore depends on an implementation adopting this template and passing untrusted input into it. ### Attack Path 1. An application copies the documented cache implementation into executable code. 2. The application accepts a stock code, date, or frequency from an untrusted user or upstream source. 3. The attacker supplies a value containing path separators and traversal components, such as a stock-code value beginning with `../../`. 4. `get_cache_path` combines ...[truncated 1129 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Validate each input against a strict allowlist: - Stock code: expected exchange prefix and numeric stock-code format only. - Dates: parse as dates and serialize into a fixed format such as `YYYYMMDD`. - Frequency: accept only documented values such as `d`, `w`, `m`, `5`, `15`, `30`, or `60`. 2. Reject path separators, null bytes, traversal sequences, and unexpected punctuation. 3. Prefer generating the filename from normalized values or a cryptographic hash rather than raw input. 4. Resolve both the cache root and candidate path and verify containment before any read or write: ```python from pathlib import Path import hashlib CACHE_DIR = Path("data_cache").resolve() ALLOWED_FREQUENCIES = {"d", "w", "m", "5", "15", "30", "60"} def get_cache_path(code, start_date, end_date, freq): if not code.isdigit() or len(code) != 6: raise ValueError("Invalid stock code") if freq not in ALLOWED_FREQUENCIES: raise ValueError("Invalid frequency") cache_key = hashlib.sha256( f"{code}|{start_date}|{end_date}|{freq}".encode("utf-8") ).hexdigest() CACHE_DIR.mkdir(parents=True, exist_ok=True) candidate = (CACHE_DIR / f"{cache_key}.csv").resolve() if candidate.parent != CACHE_DIR: raise ValueError("Cache path escapes the cache directory") return candidate ``` 5. Make `load_cache` and `save_cache` accept only validated paths produced by the cache-path function. 6. Use restrictive filesystem permissions for the cache directory. 7. Consider atomic writes through a securely created temporary file inside `CACHE_DIR`, followed by a controlled rename. ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (3)

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
The skill description and the entire operational guidance are written as a Chinese-only skill for A股 financial data, with no indication that users may choose another language or locale. Under the language/locale policy, forcing a specific language without user opt-in is a natural-language policy violation unless the constraint is clearly documented and justified.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The skill includes a self-updating documentation mechanism that causes the agent to change its own operating guide, even though the skill is presented as a self-contained data-reading skill. This expands scope from read/query behavior into persistent modification behavior, which can be abused for prompt injection persistence, instruction drift, or embedding inaccurate or adversarial content into future runs.

Intent-Code Divergence

Medium
Confidence
92% confidence
Finding
The skill instructs the agent to append new content to its own guide based on future interactions and trial-and-error. That creates a self-modifying prompt/documentation channel unrelated to simple financial-data retrieval, allowing untrusted runtime inputs to persist into the skill and potentially poison future behavior or instructions.

Static analysis

No suspicious patterns detected.