Back to skill

Security audit

trading-agents.skill

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent stock-analysis workflow, but it unsafely places user-provided tickers into shell commands and output filenames, so it should be reviewed before use.

Before installing, treat this as a review-needed skill: run it only in a sandboxed workspace, use simple validated stock symbols, avoid passing untrusted ticker text, and prefer a version that validates tickers, avoids shell command strings, confines output paths, and ships a reviewed lockfile. Remember that its output is research assistance, not 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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
agents/technical_analyst.md:11
Finding
User-Controlled Ticker Interpolated into Shell Commands<![CDATA[ ## Vulnerability Details **File Location**: - `SKILL.md:64-69` - `agents/fundamental_analyst.md:13-17` - `agents/technical_analyst.md:11-21` **Vulnerability Type**: OS command injection through unquoted template substitution **Risk Level**: High ### Vulnerable Code `SKILL.md:64-69` defines the ticker as a value extracted from the user's message without requiring validation: ```markdown Extract from the user's message: - **Ticker(s)**: The stock symbol(s) to analyze (e.g., NVDA, AAPL) - **Date context**: Whether they want current analysis or historical (default: today) - **Debate rounds**: If specified, how many bull/bear rounds (default: 1) - **Focus areas**: Any specific concerns (e.g., "worried about earnings", "considering for long-term hold") ``` `agents/fundamental_analyst.md:13-17` inserts that value directly into a shell command: ```markdown 1. **Run the market data script** to get financial statements and key metrics: ```bash cd {SKILL_PATH} && uv run scripts/fetch_market_data.py {TICKER} ``` ``` `agents/technical_analyst.md:11-21` repeats the unsafe pattern: ```markdown 1. **Run the market data script** to get price history: ```bash cd {SKILL_PATH} && uv run scripts/fetch_market_data.py {TICKER} ``` 2. **Run the technical indicators script**: ```bash cd {SKILL_PATH} && uv run scripts/technical_indicators.py {TICKER} ``` ``` ### Technical Analysis The `{TICKER}` placeholder is derived from untrusted user input and is inserted unquoted into Bash command templates. No validation or normalization rule limits this value to characters valid in a stock symbol. If the resulting command is passed to a shell, metacharacters such as semicolons, command substitutions, redirection operators, or logical operators are interpreted as shell syntax rather than as part of a ticker argument. Quoting alone would reduce the immediate risk, but argument-array execution combined with strict input validation is the safer desig ...[truncated 1522 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Validate the ticker before it reaches any command: - Use an explicit allowlist appropriate to supported exchanges. - A baseline rule could be `^[A-Za-z0-9.^-]{1,20}$`. - Reject control characters, whitespace, path separators, and shell metacharacters. - Where exchange-specific suffixes are supported, define them explicitly rather than broadening the rule indiscriminately. 2. Do not execute generated command strings through a shell. Invoke the process with a structured argument array equivalent to: ```python subprocess.run( ["uv", "run", "scripts/fetch_market_data.py", validated_ticker], cwd=skill_path, check=True, shell=False, ) ``` 3. Apply the same protection to the technical-indicator invocation. 4. Avoid generating executable Bash snippets in subagent prompts when the orchestration layer can invoke the scripts directly. 5. Resolve and validate `SKILL_PATH` separately. Pass it through a working-directory parameter instead of interpolating it into `cd`. 6. Add regression tests using ticker values containing semicolons, command substitutions, redirection operators, newlines, spaces, and path separators. Confirm that every invalid value is rejected before execution. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/fetch_market_data.py:200
Finding
Ticker-Derived Output Filenames Allow Path Traversal<![CDATA[ ## Vulnerability Details **File Location**: - `scripts/fetch_market_data.py:200-211` - `scripts/technical_indicators.py:295-306` **Vulnerability Type**: Path traversal and unintended file write **Risk Level**: Medium ### Vulnerable Code `scripts/fetch_market_data.py:200-211`: ```python parser = argparse.ArgumentParser(description="Fetch market data for a stock ticker") parser.add_argument("ticker", help="Stock ticker symbol (e.g., NVDA, AAPL)") parser.add_argument("--output", "-o", default=".", help="Output directory") args = parser.parse_args() ticker = args.ticker.upper() output_dir = Path(args.output) output_dir.mkdir(parents=True, exist_ok=True) print(f"Fetching market data for {ticker}...") data = fetch_data(ticker) output_file = output_dir / f"{ticker}_market_data.json" ``` The subsequent write occurs at `scripts/fetch_market_data.py:212-213`: ```python with open(output_file, "w") as f: json.dump(data, f, indent=2, default=str) ``` `scripts/technical_indicators.py:295-306`: ```python parser = argparse.ArgumentParser( description="Compute technical indicators for a stock" ) parser.add_argument("ticker", help="Stock ticker symbol (e.g., NVDA, AAPL)") parser.add_argument("--output", "-o", default=".", help="Output directory") args = parser.parse_args() ticker = args.ticker.upper() output_dir = Path(args.output) output_dir.mkdir(parents=True, exist_ok=True) print(f"Computing technical indicators for {ticker}...") data = compute_indicators(ticker) output_file = output_dir / f"{ticker}_technical_indicators.json" ``` The subsequent write occurs at `scripts/technical_indicators.py:307-308`: ```python with open(output_file, "w") as f: json.dump(data, f, indent=2, default=str) ``` ### Technical Analysis Both scripts use the unvalidated ticker as part of an output filename. Calling `.upper()` changes letter case but does not remove `..`, `/`, `\`, or absolute-path prefixes. A ticker containing traversal components can cause the ...[truncated 1827 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Apply the same strict ticker allowlist used to prevent command injection before using the ticker in any path. 2. Generate filenames from a sanitized identifier rather than directly from user input: ```python import re if not re.fullmatch(r"[A-Za-z0-9.^-]{1,20}", args.ticker): parser.error("Invalid ticker symbol") ticker = args.ticker.upper() ``` 3. Resolve the output directory and candidate file and enforce containment: ```python output_dir = Path(args.output).resolve() output_dir.mkdir(parents=True, exist_ok=True) output_file = (output_dir / f"{ticker}_market_data.json").resolve() if output_file.parent != output_dir: raise ValueError("Output path escapes the selected directory") ``` 4. Apply equivalent containment checks in `technical_indicators.py`. 5. Where practical, use an application-generated filename or a hash of the validated ticker. 6. Add tests for `../`, absolute paths, nested paths, backslash-based traversal, Unicode separators, empty values, and excessively long ticker values. ]]>

T08 · Insecure Dependencies

Warning
Location
pyproject.toml:7
Finding
Unpinned and Unlocked Runtime Dependency Installation<![CDATA[ ## Vulnerability Details **File Location**: - `SKILL.md:25-33` - `pyproject.toml:7-12` - Project root: no `uv.lock` is present in the supplied directory structure **Vulnerability Type**: Non-reproducible third-party dependency installation **Risk Level**: Medium ### Vulnerable Code `SKILL.md:25-33` instructs the runtime to upgrade the installer and synchronize dependencies from external package sources: ```markdown 1. Install uv (if not already installed): ```bash pip install -U uv ``` 2. Sync the project dependencies from the skill directory: ```bash cd {SKILL_PATH} && uv sync ``` ``` `pyproject.toml:7-12` specifies only minimum versions: ```toml dependencies = [ "akshare>=1.18.51", "numpy>=2.0.2", "pandas>=2.3.3", "yfinance>=1.2.0", ] ``` No `uv.lock` file is present in the audited project structure. ### Technical Analysis The Skill installs the newest `uv` version available and permits any dependency release equal to or newer than the listed minimum. Without a committed lockfile, the exact direct and transitive dependency graph can change between runs without any corresponding change to the audited Skill. Python packages execute code when imported, and installation mechanisms may also process build-system code for source distributions. Consequently, a compromised package release, compromised maintainer account, malicious transitive dependency, or unsafe package-index configuration could introduce code that was never part of the reviewed artifact. This finding does not establish that any currently named package is malicious. It identifies a supply-chain control weakness that allows future dependency contents to change after review. ### Attack Path 1. A dependency or transitive dependency publishes a compromised release that satisfies the broad version constraints, or the configured package source serves an attacker-controlled artifact. 2. A user follows `SKILL.md` and runs `pip install -U uv` or `uv syn ...[truncated 950 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Generate and commit a reviewed `uv.lock` file containing the complete resolved dependency graph. 2. Require locked or frozen synchronization so dependency resolution fails rather than silently selecting new versions. 3. Pin the `uv` installer to a reviewed version instead of running an unconditional upgrade: ```bash python -m pip install "uv==<reviewed-version>" ``` 4. Prefer binary wheels from a trusted, explicitly configured package index. Verify the index URL and prevent unintended fallback to untrusted repositories. 5. Use hash verification where supported and review hashes whenever dependencies are updated. 6. Remove dependencies that are not required by the shipped scripts. In particular, verify whether `akshare` is necessary, because the audited scripts directly import only `yfinance`, `pandas`, and standard-library modules. 7. Integrate dependency vulnerability and provenance scanning into release review. 8. Perform dependency upgrades as explicit, reviewed changes rather than allowing runtime synchronization to select arbitrary future versions. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • 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 (19)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The description presents a sophisticated trading-analysis orchestration skill built around multiple specialized Claude subagents that collaborate to produce trading recommendations. The actual code does not implement any agent orchestration, debate, analysis pipeline, or decision-making framework. It simply retrieves market and financial data for a ticker using yfinance, stores it in JSON, and prints a few summary fields. While fetching market data could be a supporting component of a trading-analysis system, this code chunk’s primary behavior is data collection/export, which is materially narrower and different from the declared purpose.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description describes a broad multi-agent trading analysis framework modeled after TradingAgents, with many specialized subagents collaborating on investment decisions. The supplied code chunk does not do any orchestration or agent simulation. It is a standalone technical-analysis utility focused solely on computing price-based indicators for a ticker and saving them to JSON. While technical analysis is one component mentioned in the description, the actual code's primary purpose is far narrower and materially different from the declared system-level functionality. Therefore this is a clear description/behavior mismatch.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill instructs the agent to create report files and working artifacts, but it does not declare any explicit tool scope such as permissions or allowed-tools. In a multi-agent workflow that writes multiple outputs, missing tool boundaries increases the chance of unintended file writes or broader filesystem access than reviewers expect.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The activation criteria are very broad, causing the skill to trigger on a wide range of ordinary investment conversations. In context, this is risky because the skill launches a costly, multi-step workflow with subagents, external data retrieval, and file generation, potentially causing unnecessary tool use, excess token spend, and user confusion without clear intent.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The debate record format requires Chinese headings like "辩论背景", "第 N 轮辩论", and "研究经理总结" regardless of the user's requested language. Elsewhere the file also mixes Chinese-specific output examples, but this section is a direct formatting requirement and does not offer the user a language choice.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
Lines L140-L147 require the report to include a section titled "数据来源" and provide citation examples entirely in Chinese. This imposes a specific language/locale convention on output without user opt-in or a stated regional justification, which matches the language-policy violation criteria.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The instructions require the final report to include a section titled `数据来源` and use Chinese-language citation examples, which imposes a specific language format. There is no opt-in, user choice, or documented regional justification for forcing this locale-specific output.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The file requires source attribution and source-section formatting using Chinese-language examples and headings such as "数据来源," and it prioritizes Chinese-language platforms as mandatory for certain stocks. This imposes a specific language/locale convention on the report without offering the user a language choice or documenting a justified locale restriction.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The skill hard-codes Chinese-language output/examples for parts of the report without any user opt-in, which can override user preferences and create instruction-conflict behavior in downstream agent outputs. In a trading-analysis skill, this is not directly code-execution or data-exfiltration dangerous, but it can degrade reliability, cause confusing mixed-language reports, and make the agent easier to steer away from the user's requested format.

Missing User Warnings

Low
Confidence
81% confidence
Finding
This markdown skill instructs the agent to save output to `{OUTPUT_DIR}/bear_case.md`, which affects user data/filesystem state. The file does not include any warning or disclosure that it will write a file, nor any confirmation or caution about overwriting or creating output artifacts.

Missing User Warnings

Low
Confidence
86% confidence
Finding
This markdown skill instructs saving a report to `{OUTPUT_DIR}/bull_case.md`, which is a file write operation. The description does not include any warning or disclosure that the skill will create or overwrite a file, so users may not realize it modifies the filesystem.

Missing User Warnings

Low
Confidence
86% confidence
Finding
This markdown skill directs the agent to write a report to `{OUTPUT_DIR}/news_analysis.md`, which affects local user data. The description does not include any warning about file creation/overwrite behavior or its impact on the workspace.

Natural-Language Policy Violations

Low
Confidence
72% confidence
Finding
Line L34 includes the Chinese term `拨备覆盖率` in otherwise English instructions. This can impose a language expectation without explicit user opt-in or explanation of why a multilingual term is required.

Missing User Warnings

Low
Confidence
96% confidence
Finding
Line L57 directs the agent to save output to `{OUTPUT_DIR}/risk_assessment.md`, which is a file write operation. The markdown does not include any warning or disclosure that the skill will create or overwrite a file in the user's filesystem.

Missing User Warnings

Low
Confidence
90% confidence
Finding
This markdown skill explicitly instructs the agent to save a report to `{OUTPUT_DIR}/trading_recommendation.md`, which is a file write operation. The description provides no warning or disclosure that the skill will create or overwrite a file on the user's system.

Intent-Code Divergence

Low
Confidence
91% confidence
Finding
The package metadata says "Add your description here," which conflicts with the manifest's detailed claim that this skill orchestrates multi-agent stock analysis and trading recommendations. This is an intent/documentation mismatch because the embedded project description does not describe the actual stated purpose at all.

Unverifiable Dependency: numpy has 16 known advisory(ies) (CVE-2014-1859 (Numpy arbitrary file write via symlink attack); CVE-2021-41495 (NumPy NULL Pointer Dereference); CVE-2021-33430 (NumPy Buffer Overflow (Disputed)) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

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
40% confidence
Finding
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Description-Behavior Mismatch

Low
Confidence
88% confidence
Finding
The module docstring frames the script as computing technical indicators, while the implementation also creates an output directory and writes a JSON file to it. Because the documentation's usage text mentions an output path and says it outputs JSON, this is only a mild mismatch at the top-level description rather than a hidden capability.

Static analysis

No suspicious patterns detected.