Back to skill

Security audit

Yahoo

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a coherent Yahoo Finance helper, but its briefing script can read any local file path supplied with --file and send each line to Yahoo as a quote lookup.

Review before installing. The skill does not show malicious intent, order placement, credential collection, or hidden persistence, but only use yahoo_brief.py --file with a known watchlist file, preferably under ~/yahoo/. Do not point it at .env files, notes, exports, or other private local files, because their lines may be sent to Yahoo Finance as quote lookups.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
yahoo_brief.py:34
Finding

Arbitrary Local File Contents Can Be Transmitted to Yahoo Finance

Content
View full analysis

Vulnerability Details

File Location: yahoo_brief.py:34-40, 62-80, 104-110
Vulnerability Type: Unvalidated local-file input leading to unintended network disclosure
Risk Level: Medium

Vulnerable Code

python
def fetch_html(symbol: str) -> str:
    req = Request(f"https://finance.yahoo.com/quote/{symbol}", headers=HEADERS)
    with urlopen(req, timeout=20) as response:
        payload = response.read()
        encoding = (response.info().get("Content-Encoding") or "").lower()
    if encoding == "gzip" or payload[:2] == b"\x1f\x8b":
        payload = gzip.decompress(payload)
    return payload.decode("utf-8", "replace")
python
def load_symbols(args_symbols: list[str], file_path: str | None) -> list[str]:
    symbols = [item.upper() for item in args_symbols]
    if file_path:
        path = Path(file_path).expanduser()
        for line in path.read_text(encoding="utf-8").splitlines():
            line = line.strip().upper()
            if line and not line.startswith("#"):
                symbols.append(line)
    seen = set()
    unique = []
    for symbol in symbols:
        if symbol not in seen:
            seen.add(symbol)
            unique.append(symbol)
    return unique


def fetch_snapshot(symbol: str) -> Snapshot:
    page = fetch_html(symbol)
python
snapshots: list[Snapshot] = []
failures: list[str] = []
for symbol in symbols:
    try:
        snapshots.append(fetch_snapshot(symbol))
    except Exception as exc:
        failures.append(f"{symbol}: {exc}")

Technical Analysis

The --file option accepts an arbitrary local path and reads every nonempty, non-comment line from that file. The application assumes each line is a Yahoo Finance symbol but does not validate it against an acceptable ticker syntax, restrict the file to an approved watchlist directory, or limit the size and number of entries.

Each loaded line is ...[truncated 2108 chars]

Remediation
View remediation

Remediation Suggestions

  1. Validate every symbol before any network request. Use a conservative allowlist appropriate for supported Yahoo symbols and reject lines containing whitespace, assignment operators, URL delimiters, control characters, or excessive length. For example:

    python
    SYMBOL_PATTERN = re.compile(r"^[A-Z0-9^][A-Z0-9.^=_-]{0,31}$")
    
    def validate_symbol(symbol: str) -> str:
        normalized = symbol.strip().upper()
        if not SYMBOL_PATTERN.fullmatch(normalized):
            raise ValueError(f"Invalid Yahoo symbol: {symbol!r}")
        return normalized
    

    The exact pattern should be tested against all legitimately supported equity, ETF, index, currency, and cryptocurrency symbol formats.

  2. Restrict file access to approved watchlist locations. Resolve the requested path and verify that it is located under an expected directory such as ~/yahoo/. Reject paths outside that directory unless the user gives explicit, informed confirmation.

  3. Require an appropriate watchlist format. Prefer a dedicated file such as ~/yahoo/watchlist.md or a structured JSON format whose schema permits only ticker fields. Do not interpret every arbitrary text-file line as a symbol.

  4. Apply resource limits. Enforce a maximum file size, maximum line length, and maximum number of symbols to prevent excessive memory use and unintended request floods.

  5. Validate command-line symbols too. Apply the same validation to positional symbols so all input paths have identical security controls.

  6. Fail safely before networking. Parse and validate the complete watchlist first. If any entry is invalid, report it locally and do not transmit that entry.

  7. Add regression tests. Verify rejection of sensitive-file-style inputs such as API_KEY=SECRET, private-key lines, absolute paths, URL fragments, control characters, and oversized entries while retaining support for legitimate symbols such as `A ...[truncated 41 chars]

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (9)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code is narrowly focused on generating a Yahoo Finance market brief for explicitly supplied ticker symbols. It does support quote retrieval and market-brief generation, which aligns with part of the description. However, it does not perform symbol search, manage watchlists in any meaningful Yahoo/watchlist sense, or provide catalyst-aware analysis or stock decision logic. There are no undeclared dangerous capabilities, but the declared description overstates the implemented functionality, so this is a description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description suggests a broader finance assistant with multiple capabilities: quotes, symbol search, watchlists, market briefs, and decision support based on catalysts. The supplied code only performs one narrow function: downloading a Yahoo Finance quote page for one symbol and extracting/displaying quote fields and some statistics. It does use Yahoo Finance for quotes, so that portion is accurate, but the overall description materially overstates the implemented capabilities. There are no undeclared risky behaviors or extra permissions apparent; the mismatch is that most declared features are not implemented in this code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code is narrowly focused on Yahoo Finance search functionality: it sends a query to Yahoo's finance search endpoint, retrieves JSON, and displays symbol matches and related headlines. This partially aligns with the declared 'symbol search' and loosely with headlines/news, but it does not implement watchlists, detailed quote retrieval, market briefs, or any catalyst-aware decision logic. There are no suspicious undeclared capabilities beyond outbound access to Yahoo's public API, which is consistent with the description's Yahoo Finance theme. The mismatch is because the declared description significantly overstates the implemented functionality.

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · risk-playbook.md (reported line 21)May include surrounding context.

md
- User has no stated horizon
- User is asking for certainty instead of scenarios

## Output rules

- If risk is unclear, downgrade to watchlist or needs more confirmation.
- If the user wants a trade-style answer, include invalidation and what evidence would reverse the call.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill declares network access and local file usage behavior in prose, but it does not define an explicit tool scope such as permissions or allowed-tools. That creates an authorization ambiguity where an agent runtime may grant broader file-read or network capabilities than the minimally necessary Yahoo-only behavior, increasing the chance of unintended data exposure or overprivileged execution.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · setup.md (reported line 18)May include surrounding context.

bash
mkdir -p ~/yahoo
touch ~/yahoo/memory.md ~/yahoo/watchlist.md ~/yahoo/briefing-log.md ~/yahoo/decisions.md
chmod 700 ~/yahoo
chmod 600 ~/yahoo/memory.md ~/yahoo/watchlist.md ~/yahoo/briefing-log.md ~/yahoo/decisions.md

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · setup.md (reported line 19)May include surrounding context.

mkdir -p ~/yahoo touch ~/yahoo/memory.md ~/yahoo/watchlist.md ~/yahoo/briefing-log.md ~/yahoo/decisions.md chmod 700 ~/yahoo chmod 600 ~/yahoo/memory.md ~/yahoo/watchlist.md ~/yahoo/briefing-log.md ~/yahoo/decisions.md

text

If `~/yahoo/memory.md` is empty, initialize it from `memory-template.md`.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The proposed AGENTS.md routing snippet uses broad triggers like 'stock quotes,' 'market briefs,' and 'pre-market moves,' which can cause the Yahoo skill to activate in situations broader than the user may intend. In an agent environment, overly generic routing increases the chance of unintended tool invocation, unnecessary access to local memory files, and decision-making flows being applied to loosely related financial discussions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script transmits the user's raw query to Yahoo Finance over the network without any explicit notice, consent flow, or privacy warning. While this is expected for a search tool, it can still expose sensitive user-entered terms such as proprietary watchlist ideas, internal company names, or research topics to a third party.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.