Back to skill

Security audit

Market Events

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed market-data helper that reads user-provided tickers, uses an FMP API key to query FMP, and prints event results without persistence or hidden side effects.

Before installing, provide only an FMP API key you are comfortable using with this skill and pass ticker-list files intentionally. Prefer pinning requests to a reviewed version or installing from a locked environment for reproducible dependency behavior.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Unpinned Third-Party Dependency Permits Unreviewed Package Updates

Content
View full analysis

Vulnerability Details

File Location: requirements.txt:1 and SKILL.md:109
Vulnerability Type: Unpinned third-party dependency
Risk Level: Low

Vulnerable code and installation guidance:

requirements.txt:1

text
requests

SKILL.md:109

markdown
- Requires the `requests` library (`pip install requests`).

Technical Analysis

The project installs requests without constraining its version or verifying an artifact hash. Consequently, separate installations can resolve to different package releases. A future compromised, malicious, or incompatible release could be installed automatically without undergoing the same review as the audited project.

This is a supply-chain hardening issue rather than evidence that the current requests package is malicious. The dependency name is legitimate, and the audit found no typosquatting or dependency-confusion package name.

Attack Path

  1. An attacker compromises the upstream package, a package maintainer account, or the package distribution channel.
  2. The attacker publishes a malicious release under the legitimate requests package name.
  3. A user installs the project dependencies using pip install -r requirements.txt or follows the documented pip install requests command.
  4. Because no version or hash is enforced, the resolver selects the malicious release.
  5. Malicious package installation or runtime code executes with the privileges of the user running the installation or Skill.

Exploitation therefore depends on an upstream supply-chain compromise or equivalent package-resolution attack.

Impact Assessment

A malicious resolved dependency could execute code with the same operating-system privileges as the installing or invoking user. Within those privileges, it could access files and environment variables available to the process, including FMP_API_KEY, alter application behavior, send data over the network, or compr ...[truncated 142 chars]

Remediation
View remediation

Remediation Suggestions

  • Pin requests to a reviewed version, for example with an exact == constraint.
  • Generate and commit a lock file containing all transitive dependency versions.
  • Require cryptographic hashes during installation, such as through a hash-locked requirements file and pip --require-hashes.
  • Install packages only from an explicitly trusted package index over HTTPS.
  • Use automated dependency scanning and controlled update reviews before changing pinned versions.
  • Update SKILL.md so its manual installation command uses the same reviewed version and installation policy as requirements.txt.
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • 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
Findings (8)

Tainted flow: 'params' from os.environ.get (line 273, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · market-events.py (reported line 165)May include surrounding context.

python
params = {"symbol": ticker, "apikey": api_key}

    try:
        resp = requests.get(url, params=params, timeout=30)
    except requests.RequestException as e:
        print(f"Warning: Network error fetching dividends for {ticker}: {e}", file=sys.stderr)
        return []

Tainted flow: 'params' from os.environ.get (line 273, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · market-events.py (reported line 248)May include surrounding context.

python
params = {"symbol": ticker, "apikey": api_key}

    try:
        resp = requests.get(url, params=params, timeout=30)
    except requests.RequestException as e:
        print(f"Warning: Network error fetching dividends for {ticker}: {e}", file=sys.stderr)
        return []

Tainted flow: 'params' from os.environ.get (line 273, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · market-events.py (reported line 281)May include surrounding context.

python
params = {"symbol": ticker, "apikey": api_key}

    try:
        resp = requests.get(url, params=params, timeout=30)
    except requests.RequestException as e:
        print(f"Warning: Network error fetching dividends for {ticker}: {e}", file=sys.stderr)
        return []

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill invokes Python, reads user-supplied files, accesses the FMP_API_KEY from the environment, and performs outbound network requests, but the manifest does not declare an explicit tool scope such as permissions or allowed-tools. This creates a trust and containment gap: a reviewer or runtime policy engine cannot easily verify that the skill's actual capabilities match its declared access, increasing the risk of unintended data access or network use if the implementation changes or is abused.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest describes a skill that reports upcoming or recent earnings, dividends, and stock splits from FMP in a date range, implying comparable calendar-style retrieval across event types. However, the implementation uses a different capability for dividends: it calls the per-symbol /dividends endpoint and locally filters historical dividend records, which is materially different from the documented dividends-calendar behavior and can change completeness or semantics of results.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The docstring states that this function fetches dividends for a single ticker via /stable/dividends and filters by date range, suggesting that dividend handling follows this path. In reality, main() never calls this function; dividends are fetched through the generic fetch_events() path using the dividends-calendar endpoint, so the inline documentation describes behavior the program does not perform.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency manifest specifies requests without a version pin, which makes builds non-reproducible and can cause the skill to install an unexpectedly vulnerable or incompatible release. In a network-facing skill that retrieves market data from an external API, dependency drift increases supply-chain risk and makes it harder to verify whether known fixes are present.

Content

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

text
requests

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +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
92% confidence
Finding

Because requests is unpinned, it is impossible to determine from this manifest whether deployment will use a release affected by known advisories, including issues involving credential leakage or TLS/verification behavior. This skill's purpose involves outbound HTTP requests to a market data provider, so using an unknown requests version creates avoidable exposure in the HTTP client layer.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.