Back to skill

Security audit

yf-stats

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent stock-data purpose, but its command template can pass user-controlled input to a shell unsafely.

Install only if you trust the publisher and can run it in a restricted environment. The skill should validate ticker symbols, pass command arguments without shell interpolation, write charts only to a dedicated safe directory, and pin dependencies before broad use.

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
SKILL.md:9
Finding
Shell Command Injection Through Unquoted Ticker Interpolation## Vulnerability Details **File Location**: `SKILL.md`, line 9 **Vulnerability Type**: OS command injection **Risk Level**: High **Vulnerable Code**: ```yaml command: "python3 yf_scraper.py {{ticker}} {{chart_flag}}" ``` ### Technical Analysis The command template places the user-derived `ticker` value directly into a command string without shell quoting, validation, or argument-boundary enforcement. If the skill runtime executes this template through a shell, shell metacharacters in the ticker are interpreted as command syntax rather than as part of a stock symbol. Although the Python script uses `argparse`, that validation occurs only after the shell has parsed the command. It therefore cannot prevent injection at the command-template layer. ### Attack Path 1. An attacker submits a ticker containing shell syntax, such as `AAPL; id > /tmp/yf-proof #`. 2. The value is interpolated into the template: ```sh python3 yf_scraper.py AAPL; id > /tmp/yf-proof # ``` 3. If the runtime invokes the resulting string through a shell, the shell runs the scraper and then executes the injected `id` command. 4. The attacker can substitute other commands to read, modify, or delete data available to the skill process, or execute locally installed programs. ### Impact Assessment Successful exploitation permits arbitrary command execution with the operating-system privileges of the Agent or skill runtime. The affected scope includes files, environment variables, credentials, network access, and other resources available to that process. This issue does not independently provide privilege escalation beyond the runtime account, but it can fully compromise that account's accessible environment.
Remediation
## Remediation Suggestions - Do not execute an interpolated command through a shell. Pass arguments as a structured array, for example `["python3", "yf_scraper.py", ticker]`. - Validate the ticker before command construction using a strict allowlist appropriate to supported exchanges, such as `^[A-Za-z0-9.^-]{1,20}$`. - Represent chart selection as an internal boolean and append the fixed literal `--chart` only when needed. Do not accept arbitrary text for `chart_flag`. - If the runtime only supports string templates, apply its documented shell-safe argument mechanism rather than manually concatenating values. - Run the skill under a least-privileged account with restricted filesystem and network access to limit the impact of any command-layer vulnerability.

T09 · Insecure Skill Coding Practices

Warning
Location
yf_scraper.py:27
Finding
Path Traversal Through User-Controlled Chart Filename## Vulnerability Details **File Location**: `yf_scraper.py`, lines 27-28 **Vulnerability Type**: Path traversal and arbitrary file write **Risk Level**: Medium **Vulnerable Code**: ```python filename = f"{ticker_symbol}_chart.png" plt.savefig(filename) ``` ### Technical Analysis The ticker is incorporated directly into a filesystem path. The only transformation applied before `get_data` receives it is conversion to uppercase; this does not remove path separators, `..` traversal components, absolute-path syntax, or other filesystem-significant characters. Consequently, a malicious ticker can cause `plt.savefig` to resolve the output outside the intended working directory. The generated content is a PNG, but the operation can still create or overwrite any path that can be represented by the resulting filename and is writable by the process. ### Attack Path 1. The attacker supplies a ticker containing traversal components, such as `../../tmp/report`. 2. The program converts it to uppercase but preserves the traversal syntax. 3. With chart generation enabled, the filename becomes: ```text ../../TMP/REPORT_chart.png ``` 4. `plt.savefig` resolves that relative path from the process working directory. 5. If the destination directory exists and is writable, the process creates or overwrites the targeted file outside the expected chart-output directory. Exploitation is constrained by the automatically appended `_chart.png` suffix, path existence, filesystem permissions, and platform path semantics. ### Impact Assessment An attacker may create or overwrite PNG-suffixed files in directories writable by the skill process. This can cause data loss, interfere with other application files, consume storage, or place attacker-triggered content in unintended locations. The vulnerability does not by itself bypass operating-system permissions or permit arbitrary file content.
Remediation
## Remediation Suggestions - Apply strict ticker validation before making network requests or constructing filenames. Reject path separators, traversal components, control characters, and unsupported symbols. - Generate a safe filename from a validated identifier rather than from raw input. - Write charts only to a dedicated output directory. - Resolve the candidate path and verify that it remains beneath the resolved output directory before writing. - Use non-overwriting creation semantics or a server-generated unique filename where feasible. - Return the safe generated path separately from the original ticker. Example hardening approach: ```python import re from pathlib import Path if not re.fullmatch(r"[A-Z0-9.^-]{1,20}", ticker_symbol): raise ValueError("Invalid ticker symbol") output_dir = Path("charts").resolve() output_dir.mkdir(mode=0o700, parents=True, exist_ok=True) filename = output_dir / f"{ticker_symbol}_chart.png" plt.savefig(filename) ```

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding
Non-Reproducible Dependency Resolution Through Unbounded Version Ranges## Vulnerability Details **File Location**: `requirements.txt`, lines 1-3 **Vulnerability Type**: Unpinned third-party dependencies **Risk Level**: Low **Vulnerable Code**: ```text yfinance>=0.2.40 pandas>=2.0.0 matplotlib>=3.8.0 ``` ### Technical Analysis Each dependency specifies only a minimum version and permits the package resolver to install any later release. This makes installations non-reproducible and allows future, unreviewed versions of the packages and their transitive dependencies to enter the runtime automatically. No evidence in the audited files establishes that the named packages or currently resolved versions are malicious. The security issue is the absence of version and integrity controls, which increases exposure if a future release is compromised, malicious, or introduces a security regression. ### Attack Path 1. The project is installed or rebuilt at a later time. 2. The package resolver selects newer versions satisfying the open-ended constraints. 3. A newly selected direct or transitive dependency contains malicious code or a security regression. 4. Package installation hooks or imported runtime code execute in the project environment. 5. That code receives the privileges and resource access of the installation or skill process. This path depends on a compromised or vulnerable future dependency release; the manifest alone does not demonstrate an active malicious dependency. ### Impact Assessment The potential scope includes code execution during installation or runtime, access to files and environment variables available to the process, dependency API breakage, and inconsistent security behavior between deployments. Actual impact depends on the selected package versions and the privileges used for installation and execution.
Remediation
## Remediation Suggestions - Generate a reviewed lock file that pins exact direct and transitive dependency versions. - Use hashes for downloaded artifacts, such as pip hash-checking mode with `--require-hashes`. - Install only from approved package indexes over authenticated TLS. - Scan locked dependencies for known vulnerabilities in CI and before release. - Update dependencies through a controlled review process rather than resolving unrestricted future releases during deployment. - Perform installations in an isolated, least-privileged environment and avoid installing packages as an administrative user.
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (4)

Unpinned Dependencies

Low
Category
Supply Chain
Content
yfinance>=0.2.40
pandas>=2.0.0
matplotlib>=3.8.0
Confidence
96% confidence
Finding
The dependency is specified with a lower bound only, so builds may resolve to different versions over time. This weakens reproducibility and can unintentionally pull in a vulnerable or breaking upstream release, which is a real supply-chain risk even though there is no evidence of malicious intent here.

Unpinned Dependencies

Low
Category
Supply Chain
Content
yfinance>=0.2.40
pandas>=2.0.0
matplotlib>=3.8.0
Confidence
97% confidence
Finding
Using an unpinned pandas version allows installation of any future compatible release, reducing build determinism. In security terms this creates avoidable supply-chain exposure because a vulnerable or incompatible version could be installed without code changes in the skill itself.

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.

Unpinned Dependencies

Low
Category
Supply Chain
Content
yfinance>=0.2.40
pandas>=2.0.0
matplotlib>=3.8.0
Confidence
95% confidence
Finding
The unpinned matplotlib requirement permits version drift across environments. While not an immediate exploit by itself, it increases supply-chain uncertainty and can introduce security or stability issues from upstream releases.

Static analysis

No suspicious patterns detected.