Back to skill

Security audit

Backtesting Trading Strategies

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent local backtesting tool that downloads market data and saves analysis files, with no evidence of hidden control, credential access, live trading, or destructive behavior.

Install it in a dedicated virtual environment, consider pinning dependency versions, and expect it to contact market-data providers and save cached data plus reports locally. Review generated trading results as analysis only, not as instructions to place real trades.

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)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:32
Finding
Unpinned Third-Party Dependencies Create Supply-Chain Risk## Vulnerability Details **File Location**: `SKILL.md:32-38`; repeated in `references/implementation.md:23-28` and `references/errors.md:34-41` **Vulnerability Type**: Unpinned and integrity-unverified third-party dependencies **Risk Level**: Medium **Vulnerable Code Snippet**: ```bash pip install pandas numpy yfinance matplotlib ``` ```bash pip install ta-lib scipy scikit-learn ``` ### Technical Analysis The installation instructions do not constrain dependency versions or verify package integrity with cryptographic hashes. As a result, package resolution depends on the current state of the configured Python package index and the user's pip configuration at installation time. This makes the installed code mutable after the Skill has been reviewed. A compromised upstream release, dependency-confusion condition involving an untrusted package index, or unexpected incompatible release could introduce arbitrary installation-time or runtime behavior. The project does not include a lock file or hash-verified requirements file that would allow users to reproduce the audited dependency set. The audit did not identify an intentionally malicious package in the listed dependencies. The issue is the absence of controls that ensure users install the same reviewed package artifacts. ### Attack Path 1. An attacker compromises a listed dependency, one of its transitive dependencies, or a package source trusted by the victim's pip configuration. 2. The attacker publishes a malicious package version or artifact that satisfies the unconstrained dependency request. 3. A user follows the Skill instructions and executes the unpinned `pip install` command. 4. Pip resolves and installs the attacker-controlled artifact because no approved version or hash is enforced. 5. Malicious code executes during package installation or when the package is imported by the backtesting scripts. ### Impact Assessment Successful exploitation would ex ...[truncated 503 chars]
Remediation
## Remediation Suggestions 1. Create a reviewed dependency lock file containing exact versions for direct and transitive dependencies. 2. Record cryptographic hashes and install with hash verification: ```bash python -m pip install --require-hashes -r requirements.txt ``` 3. Use a dedicated virtual environment rather than a shared or system-wide Python installation: ```bash python -m venv .venv . .venv/bin/activate python -m pip install --require-hashes -r requirements.txt ``` 4. Configure pip to use an explicitly trusted package index and avoid untrusted extra indexes. 5. Regularly review and update pinned versions through a controlled dependency-update process. 6. Replace every unpinned installation command in `SKILL.md`, `references/implementation.md`, and `references/errors.md` with the same reproducible installation procedure.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/fetch_data.py:81
Finding
CoinGecko HTTP Request Lacks a Timeout## Vulnerability Details **File Location**: `scripts/fetch_data.py:81-86` **Vulnerability Type**: Unbounded external HTTP request **Risk Level**: Low **Vulnerable Code Snippet**: ```python url = f"https://api.coingecko.com/api/v3/coins/{coin_id}/market_chart" params = {'vs_currency': 'usd', 'days': days} response = requests.get(url, params=params) response.raise_for_status() data = response.json() ``` ### Technical Analysis The CoinGecko data-fetching path invokes `requests.get` without connection or read timeouts. Requests can therefore wait indefinitely if the remote endpoint, proxy, DNS path, or network connection accepts or begins the request but fails to complete it. Although `raise_for_status()` handles HTTP error responses, it does not protect against a connection that stalls before a complete response is received. No timeout exception handling, bounded retry policy, or overall execution deadline is implemented. ### Attack Path 1. A user invokes `fetch_data.py` with `--source coingecko`. 2. The request is routed to CoinGecko or through an intermediary network component. 3. The endpoint or network path accepts the connection but delays or stops transmitting the response. 4. Because no timeout is configured, the Python process remains blocked in `requests.get`. 5. The process continues consuming an execution slot and does not produce the requested data until it is externally terminated or the underlying connection eventually fails. ### Impact Assessment Exploitation affects availability rather than confidentiality or integrity. It can indefinitely block the current Skill execution and occupy an Agent worker, process slot, or automation job. No privilege escalation is obtained. The immediate scope is the fetching process, but repeated concurrent invocations could consume multiple workers or other execution resources in a service that permits parallel jobs.
Remediation
## Remediation Suggestions 1. Configure separate bounded connection and read timeouts: ```python response = requests.get( url, params=params, timeout=(5, 30), ) ``` 2. Catch timeout and connection exceptions and return a clear failure: ```python try: response = requests.get(url, params=params, timeout=(5, 30)) response.raise_for_status() except requests.Timeout as exc: raise RuntimeError("CoinGecko request timed out") from exc except requests.RequestException as exc: raise RuntimeError(f"CoinGecko request failed: {exc}") from exc ``` 3. If retries are required, use a small maximum retry count with exponential backoff and retry only transient failures. 4. Consider enforcing an overall operation deadline so retries cannot extend execution beyond the Agent's resource budget. 5. Validate the response structure and apply a reasonable response-size limit before constructing the DataFrame.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (9)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The code chunk does not implement backtesting or analytics. Its sole evident function is retrieving and caching historical price data from external sources (Yahoo Finance/CoinGecko) and writing that data to disk. While historical data fetching could support a backtesting system, this chunk by itself does not simulate trades, compute returns-based metrics, generate equity curves, or optimize parameters as the description claims. Therefore the actual behavior is materially narrower and different from the declared primary purpose.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description promises a complete backtesting capability for crypto and traditional trading strategies, including historical simulation, performance analytics, and optimization. The supplied code chunk only contains strategy definitions and signal generation methods that inspect the latest rows of price data to emit a single Signal object. While these strategy components could support a backtesting system, this chunk itself does not implement the declared primary functionality. Therefore the description materially overstates what the code actually does.

Lp1

High
Category
MCP Least Privilege
Confidence
93% confidence
Finding
This script performs outbound network access to Yahoo Finance and CoinGecko, but the finding indicates that this capability is not declared in the skill permissions. Undeclared network access is a real security issue because it expands the skill's effective privileges, can transmit user-supplied symbols and query metadata to third parties, and prevents operators from making informed trust decisions about the skill's behavior.

Description-Behavior Mismatch

Medium
Confidence
89% confidence
Finding
The manifest describes backtesting, performance metrics, and parameter optimization, but this file also retrieves historical data from the network via yfinance and persists cached CSV files locally. While data access supports backtesting, automatic network fetching and filesystem caching are additional operational behaviors not reflected in the stated description.

External Transmission

Medium
Category
Data Exfiltration
Content
coin_id = symbol_map.get(symbol.split('-')[0].upper(), symbol.lower())
    
    print(f"Fetching {coin_id} from CoinGecko...")
    url = f"https://api.coingecko.com/api/v3/coins/{coin_id}/market_chart"
    params = {'vs_currency': 'usd', 'days': days}
    
    response = requests.get(url, params=params)
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Low
Confidence
89% confidence
Finding
The skill instructs the agent to fetch historical market data from an external service and cache it locally, but it does not clearly warn the user about outbound network access and local data persistence. While not directly enabling code execution or privilege abuse, this can create transparency, privacy, and compliance issues in restricted environments where external access or local storage must be explicitly disclosed.

Missing User Warnings

Low
Confidence
83% confidence
Finding
When cached data is missing, the script makes a network request via yfinance and then saves the returned data to a local CSV cache. The code comments describe this for developers, but there is no clear user-facing disclosure in the CLI usage or output that execution may contact an external service and persist retrieved data.

Description-Behavior Mismatch

Low
Confidence
83% confidence
Finding
The manifest says the skill calculates metrics and generates equity curves, but the implementation also creates directories and saves multiple result artifacts to local files, including summaries, CSVs, and PNG charts. Persisting analysis outputs is a material behavior that is not stated in the manifest description.

Missing User Warnings

Low
Confidence
86% confidence
Finding
This code creates directories and writes summary, trades, and equity CSV output files, but provides no advance disclosure before performing the file writes. Although the function later prints where results were saved, the user is not warned beforehand that running the script will persist files under the reports/output directory.

Static analysis

No suspicious patterns detected.