Back to skill

Security audit

yahoo-fantasy-baseball

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed, read-only Yahoo Fantasy Baseball helper that stores Yahoo credentials locally and gives lineup advice without changing rosters.

Install only if you are comfortable granting this skill access to your Yahoo Fantasy Baseball data and storing Yahoo OAuth tokens locally. Run --setup and auth intentionally, protect ~/.openclaw/credentials/yahoo-fantasy/, and remember the optimizer only suggests moves; it does not apply roster changes for you.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (18)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

Most of the declared description matches the code well: it is read-only, focused on Yahoo Fantasy Baseball, and supports roster/standings/matchups/free agents/draft/transactions/injuries plus daily optimization suggestions. However, the code exposes several materially additional user-facing capabilities that are not mentioned in the declared purpose, especially MLB confirmed-lineup checks and league-wide standouts across all teams. These are not just internal implementation details; they are separate commands and behaviors. The code does not appear to perform undeclared write/modification actions, but the undeclared extra capabilities make the description incomplete enough to count as a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The code chunk is focused on MLB schedule-related lookups from statsapi.mlb.com. It provides utility functions for team normalization and for retrieving teams playing today, whether games have started, probable pitchers, opponents, matchup labels, local game times, and confirmed lineups. While some of this could support a fantasy baseball skill, the declared description promises Yahoo Fantasy league queries and roster optimization features that are not present in this code. There is no code for Yahoo authentication, league/team roster retrieval, standings, free agents, draft results, transactions, injuries, or any optimization logic. Therefore the description materially overstates and misrepresents what this code actually does.

Content

No source excerpt is available for this finding.

Memory Manipulation

High
Category
Memory Poisoning
Confidence
85% confidence
Finding

Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Content

Scanner excerpt · SKILL.md (reported line 152)May include surrounding context.

text

Three analysis categories:
1. **Lineup changes** — optimal batter assignment via constraint solver (position-aware, fills restrictive slots before UTIL). Outputs grouped swap instructions showing who starts (from bench), who gets benched, and any intermediate position reshuffles needed within that chain (e.g., a UTIL player sliding to 1B to make room). Pure position shuffles among active slots (without bench involvement) are omitted. Also checks confirmed MLB batting lineups — players confirmed not in their team's lineup are treated as unavailable (score 0) and will be moved to bench. Players whose games have already started are locked in place (Yahoo locks roster slots at first pitch) and excluded from the solver.
2. **Pitcher rotation** — priority-based pitcher slot optimization with swap suggestions. Probable starters get highest priority, then relief pitchers whose teams are playing. A starter-only arm who is **not** today's probable starter is treated as worth nothing — his team having a game is irrelevant, because he won't take the mound — so he ranks alongside pitchers whose teams are off. When nobody in contention can appear today, the pitcher already holding the slot keeps it rather than being swapped for another idle arm with better season numbers. Outputs grouped swap instructions (same format as batter swaps). Locked games are excluded.
3. **IL management** — players with IL designations (IL, IL10, IL15, IL60) not in IL slots, cleared players still in IL. DTD players are excluded since Yahoo does not allow moving them to IL.

Memory Manipulation

High
Category
Memory Poisoning
Confidence
85% confidence
Finding

Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Content

Scanner excerpt · SKILL.md (reported line 153)May include surrounding context.

text

Three analysis categories:
1. **Lineup changes** — optimal batter assignment via constraint solver (position-aware, fills restrictive slots before UTIL). Outputs grouped swap instructions showing who starts (from bench), who gets benched, and any intermediate position reshuffles needed within that chain (e.g., a UTIL player sliding to 1B to make room). Pure position shuffles among active slots (without bench involvement) are omitted. Also checks confirmed MLB batting lineups — players confirmed not in their team's lineup are treated as unavailable (score 0) and will be moved to bench. Players whose games have already started are locked in place (Yahoo locks roster slots at first pitch) and excluded from the solver.
2. **Pitcher rotation** — priority-based pitcher slot optimization with swap suggestions. Probable starters get highest priority, then relief pitchers whose teams are playing. A starter-only arm who is **not** today's probable starter is treated as worth nothing — his team having a game is irrelevant, because he won't take the mound — so he ranks alongside pitchers whose teams are off. When nobody in contention can appear today, the pitcher already holding the slot keeps it rather than being swapped for another idle arm with better season numbers. Outputs grouped swap instructions (same format as batter swaps). Locked games are excluded.
3. **IL management** — players with IL designations (IL, IL10, IL15, IL60) not in IL slots, cleared players still in IL. DTD players are excluded since Yahoo does not allow moving them to IL.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/yahoo_api.py (reported line 15)May include surrounding context.

python
CRED_DIR = Path.home() / ".openclaw" / "credentials" / "yahoo-fantasy"
CONFIG_FILE = CRED_DIR / "yahoo-fantasy.json"
OAUTH_FILE = CRED_DIR / "oauth2.json"
LEGACY_ENV_FILE = CRED_DIR / ".env"

GAME_CODE = "mlb"

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/yahoo_api.py (reported line 53)May include surrounding context.

python
def _migrate_legacy_env():
    """Auto-migrate YFPY .env credentials to oauth2.json format.

    If oauth2.json already exists, does nothing. If .env exists with
    YAHOO_CONSUMER_KEY and YAHOO_CONSUMER_SECRET, creates oauth2.json

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/yahoo_api.py (reported line 55)May include surrounding context.

python
def _migrate_legacy_env():
    """Auto-migrate YFPY .env credentials to oauth2.json format.

    If oauth2.json already exists, does nothing. If .env exists with
    YAHOO_CONSUMER_KEY and YAHOO_CONSUMER_SECRET, creates oauth2.json

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/yahoo_api.py (reported line 80)May include surrounding context.

python
def _migrate_legacy_env():
    """Auto-migrate YFPY .env credentials to oauth2.json format.

    If oauth2.json already exists, does nothing. If .env exists with
    YAHOO_CONSUMER_KEY and YAHOO_CONSUMER_SECRET, creates oauth2.json

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/yahoo_api.py (reported line 92)May include surrounding context.

python
def _migrate_legacy_env():
    """Auto-migrate YFPY .env credentials to oauth2.json format.

    If oauth2.json already exists, does nothing. If .env exists with
    YAHOO_CONSUMER_KEY and YAHOO_CONSUMER_SECRET, creates oauth2.json

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/yahoo_api.py (reported line 154)May include surrounding context.

python
def _migrate_legacy_env():
    """Auto-migrate YFPY .env credentials to oauth2.json format.

    If oauth2.json already exists, does nothing. If .env exists with
    YAHOO_CONSUMER_KEY and YAHOO_CONSUMER_SECRET, creates oauth2.json

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Confidence
85% confidence
Finding

os.system() and os exec-family calls run shell commands with the process's full privileges, enabling arbitrary command execution.

Content

Scanner excerpt · yahoo-fantasy-baseball.py (reported line 48)May include surrounding context.

python
# running. Use subprocess instead so stdin/stdout are properly inherited.
        sys.exit(subprocess.call([_VENV_PYTHON, __file__] + sys.argv[1:]))
    else:
        os.execv(_VENV_PYTHON, [_VENV_PYTHON, __file__] + sys.argv[1:])


# Handle --setup: explicitly install dependencies

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill documentation declares no explicit tool scope while instructing use of Python, local file writes, environment variables, network access, and shell execution. That creates an authorization/transparency gap: an agent or reviewer cannot easily tell what capabilities the skill requires, increasing the chance of over-privileged execution and accidental exposure of credentials or local files.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill description emphasizes querying Yahoo Fantasy Baseball data and being read-only, but these commands also call an external mlb_client to fetch schedule, lineup, matchup, and probable pitcher data. This creates a scope-expansion and data-flow transparency issue: users may reasonably expect only Yahoo-derived data, while roster context is being combined with third-party MLB sources that may have different privacy, logging, or reliability properties.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · yahoo-fantasy-baseball.py (reported line 27)May include surrounding context.

python
print("Installing dependencies...", file=sys.stderr)

    # Create venv
    subprocess.check_call(
        [sys.executable, "-m", "venv", _VENV_DIR],
        stdout=sys.stderr,
        stderr=sys.stderr,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
83% confidence
Finding

This code performs dependency installation from requirements.txt at runtime, which introduces a supply-chain risk: a tampered requirements file or compromised package source could execute arbitrary code during installation. Although setup is explicit via --setup and not silent, the skill still delegates trust to external packages without integrity verification.

Content

Scanner excerpt · yahoo-fantasy-baseball.py (reported line 35)May include surrounding context.

python
# Install requirements into the venv
    pip_cmd = [_VENV_PYTHON, "-m", "pip", "install", "-q", "-r", _REQUIREMENTS]
    subprocess.check_call(pip_cmd, stdout=sys.stderr, stderr=sys.stderr)

    print("Dependencies installed.", file=sys.stderr)

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · yahoo-fantasy-baseball.py (reported line 46)May include surrounding context.

python
# On Windows, os.execv spawns a new process and exits the current one,
        # which causes the shell to print its prompt while the child is still
        # running. Use subprocess instead so stdin/stdout are properly inherited.
        sys.exit(subprocess.call([_VENV_PYTHON, __file__] + sys.argv[1:]))
    else:
        os.execv(_VENV_PYTHON, [_VENV_PYTHON, __file__] + sys.argv[1:])

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The standouts command iterates through league.teams() and pulls rosters for every team in the league, then ranks players across the entire league. If the skill is presented primarily as operating on the user's own team, this broader analysis can expose or process other managers' roster data beyond what the user may expect, creating a transparency and least-privilege concern.

Content

No source excerpt is available for this finding.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · scripts/formatters.py (reported line 19)May include surrounding context.

python
if isinstance(obj, dict):
        val = obj.get(key, default)
    else:
        val = getattr(obj, key, default)
    if val is None:
        return default
    return val

Static analysis

No suspicious patterns detected.