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

Content
View full analysis

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
View 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

Content
View full analysis

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
View 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

Content
View full analysis

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
View 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
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.

Content

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

text
yfinance>=0.2.40
pandas>=2.0.0
matplotlib>=3.8.0

Unpinned Dependencies

Low
Category
Supply Chain
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.

Content

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

text
yfinance>=0.2.40
pandas>=2.0.0
matplotlib>=3.8.0

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.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
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.

Content

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

text
yfinance>=0.2.40
pandas>=2.0.0
matplotlib>=3.8.0