Back to skill

Security audit

Fantasy NBA 数据服务

Security checks for vulnerabilities and agentic risk

Overview

This skill appears to provide Fantasy NBA data, but it stores an API key in plaintext and has mismatched configuration names that deserve review before installation.

Install only if you trust the XiaoBenYang service and are comfortable with this skill saving your API key in a local .env file. Use a dedicated key with limited privileges if possible, keep the working directory private, and review or remove stale gaokao configuration before use.

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 (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/config.py:46
Finding

API Key Persisted in an Insecure Plaintext File

Content
View full analysis
bool: """将API key保存到.env文件""" try: env_path = Path(".env") lines = [] if env_path.exists(): lines = env_path.read_text(encoding="utf-8").splitlines() found = False new_lines = [] for line in lines: if line.startswith("XBY_APIKEY="): new_lines.append(f"XBY_APIKEY={api_key}") found = True else: new_lines.append(line) if not found: new_lines.append(f"XBY_APIKEY={api_key}") env_path.write_text("\n".join(new_lines) + "\n", encoding="utf-8") os.environ["XBY_APIKEY"] = api_key return True ``` ### Technical Analysis The function stores the API key as plaintext in a `.env` file relative to the process's current working directory. `Path.write_text()` uses ordinary filesystem permissions and does not ensure that the resulting file is accessible only to the current user. The implementation also performs no check that `.env` is a regular file rather than a symbolic link. If an attacker can prepare the working directory, a pre-created `.env` symbolic link may redirect the write to another file writable by the victim. Existing `.env` permissions are also preserved without validation. The credential is additionally copied into the process environment. Child processes started afterward could inherit it, although this project does not itself start child processes. ### Attack Path 1. An attacker obtains access to the directory from which the Skill will run, or the Skill is launched from an attacker-influenced working directory. 2. The attacker creates a permissive `.env` file or a `.env` symbolic link to another victim-writable file. 3. The us ...[truncated 943 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/call_api.py:55
Finding

Configurable Upstream Endpoint Can Receive the API Key Without Origin Validation

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (30)

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill claims to provide league analytics, but its documented behavior includes reading and writing .env, persisting API keys, and loading configuration associated with a different skill/domain. Hidden credential management and cross-domain configuration handling materially expand the attack surface and can lead to secret exposure or accidental reuse of credentials in the wrong context.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill claims to provide league analytics, but its documented behavior includes reading and writing .env, persisting API keys, and loading configuration associated with a different skill/domain. Hidden credential management and cross-domain configuration handling materially expand the attack surface and can lead to secret exposure or accidental reuse of credentials in the wrong context.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The configuration identifies itself as an unrelated '小笨羊高考' service and uses the 'XBY_GAOKAO_' prefix, which conflicts with the declared Fantasy NBA purpose. This mismatch is a strong integrity red flag because it suggests code reuse from another product or hidden coupling to a different backend, making secret handling and outbound requests less trustworthy in this context.

Content

No source excerpt is available for this finding.

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/config.py (reported line 13)May include surrounding context.

python
model_config = SettingsConfigDict(
        env_prefix="XBY_GAOKAO_",
        env_file=".env",
        env_file_encoding="utf-8",
        extra="ignore",
    )

Credential Access

High
Category
Privilege Escalation
Confidence
86% confidence
Finding

The post-init method forcibly reads .env content directly and parses out XBY_APIKEY, bypassing normal settings abstractions and explicitly targeting credential material. In the context of an unrelated Fantasy NBA skill identity, this direct secret extraction is more suspicious and increases the likelihood of mishandling, hidden coupling, or unauthorized credential reuse.

Content

Scanner excerpt · scripts/config.py (reported line 31)May include surrounding context.

python
default_year: int = 2025

    def model_post_init(self, __context):
        # 强制从 .env 文件读取 XBY_APIKEY
        env_path = Path(".env")
        if env_path.exists():
            content = env_path.read_text(encoding="utf-8")

Credential Access

High
Category
Privilege Escalation
Confidence
84% confidence
Finding

This line opens the local .env file for direct inspection as part of credential retrieval logic. Direct file reads of secret stores are more dangerous than normal environment-based injection because they encourage plaintext secret handling and make exfiltration or accidental disclosure easier if the code path expands later.

Content

Scanner excerpt · scripts/config.py (reported line 32)May include surrounding context.

python
def model_post_init(self, __context):
        # 强制从 .env 文件读取 XBY_APIKEY
        env_path = Path(".env")
        if env_path.exists():
            content = env_path.read_text(encoding="utf-8")
            for line in content.splitlines():

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/config.py (reported line 39)May include surrounding context.

python
if line.startswith("XBY_APIKEY="):
                    self.api_key = line.split("=", 1)[1].strip()
                    break
        # 如果环境变量有值,覆盖 .env 的值
        env_val = os.getenv("XBY_APIKEY", "")
        if env_val:
            self.api_key = env_val

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

This function is explicitly designed to persist an API key into a local .env file, creating durable plaintext credential storage under application control. If the working directory is accessible, backed up, logged, or accidentally committed, the secret can be stolen and used to access the backend service; the mismatch with the declared skill purpose makes this more concerning.

Content

Scanner excerpt · scripts/config.py (reported line 48)May include surrounding context.

python
def save_api_key_to_env(api_key: str) -> bool:
    """将API key保存到.env文件"""
    try:
        env_path = Path(".env")
        lines = []
        if env_path.exists():
            lines = env_path.read_text(encoding="utf-8").splitlines()

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding

The skill declares no explicit tool scope or permission boundaries even though its documented workflow includes environment access, file reads/writes, credential persistence, and network calls. In an agent setting, this over-broad implicit capability increases the chance of unintended secret access, credential modification, or misuse of external APIs because operators and users cannot easily constrain what the skill may do.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

References to a different project/domain in the workflow and structure indicate copy-paste drift or repurposed infrastructure. In security terms, this is risky because it suggests the skill may invoke wrong backends, load wrong configs, or handle user data under assumptions that do not match the advertised service.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This file contains a Chinese-only class docstring and, more importantly, user-facing exception and return messages elsewhere in the code, indicating the skill is designed to communicate in a fixed language. The file does not offer a language/locale option or document a justified regional restriction, which matches the policy-violation criteria for forced language without opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The exception message "API密钥未设置,请先调用 set_api_key()" is a user-visible string in Chinese with no apparent mechanism for selecting another language. Because the file does not provide opt-in language choice or document a justified locale restriction, this is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The function returns Chinese-language messages such as "调用小笨羊MCP API,返回统一格式" and "API调用失败" without any indication that users can choose their preferred language. This forces a locale choice in user-facing output and falls under the language-policy violation category.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This file implements credential mutation and persistence functions that are unrelated to a read-oriented Fantasy NBA statistics service. Storing and updating API keys in local project files expands the skill's capabilities into secret handling, increasing the chance of unintended credential exposure, misuse, or persistence beyond the user's expectation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The code can write API secrets to a local .env file, creating persistent plaintext storage on disk without a clear business need for a Fantasy NBA data service. This increases the attack surface because other local processes, backups, commits, or users on the system may gain access to the credential.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The function persists the provided API key to .env automatically, with no warning, confirmation, or disclosure that the credential will be stored on disk and exported into the process environment. Silent secret persistence can violate user expectations and lead to accidental long-term exposure through local files, source control, or workstation compromise.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The markdown instructs the model to use a specific Hebrew term when referring to steals, which imposes a language/locale choice in outputs regardless of the user's preferred language. This matches the policy category for language or locale constraints that are not presented as optional or user-selected.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

This line again requires use of a specific Hebrew term, creating a fixed language/locale behavior rather than offering it as an option based on user preference. Because the instruction is mandatory and not justified as a region-specific compliance need, it is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The dependency is specified with a lower bound only, which allows future installs to resolve to different versions over time. This weakens build reproducibility and can inadvertently introduce vulnerable or breaking releases, especially for a network-facing library like requests.

Content

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

text
requests>=2.31.0
pydantic>=2.7.0
pydantic-settings>=2.2.0
python-dotenv>=1.0.1

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
88% confidence
Finding

The manifest does not pin requests, and the package has multiple known advisories across versions, so there is no reliable way to determine whether deployed environments are using a safe release. Because requests is used for outbound HTTP, affected versions could expose credentials, TLS verification issues, or sensitive data depending on application usage.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
91% confidence
Finding

Using an unpinned pydantic version means deployments may pull different releases depending on install time and resolver state. That creates supply-chain and stability risk because a newly released vulnerable or incompatible version could be installed without code changes.

Content

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

text
requests>=2.31.0
pydantic>=2.7.0
pydantic-settings>=2.2.0
python-dotenv>=1.0.1

Unverifiable Dependency: pydantic has 4 known advisory(ies) (CVE-2021-29510 (Use of "infinity" as an input to datetime and date fields causes infinite loop i); CVE-2024-3772 (Pydantic regular expression denial of service); CVE-2021-29510 (Pydantic is a data validation and settings management using Python type hinting.) +1 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
84% confidence
Finding

Pydantic has known advisories in some versions, but the requirement is unpinned, making it impossible to verify whether installations are exposed. In a data service, this primarily raises risk of denial of service or parsing issues if vulnerable releases are resolved.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
89% confidence
Finding

The package pydantic-settings is not pinned to a specific version, so installations are not deterministic. This can expose the service to newly introduced vulnerabilities or behavior changes in configuration loading components.

Content

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

text
requests>=2.31.0
pydantic>=2.7.0
pydantic-settings>=2.2.0
python-dotenv>=1.0.1

Unverifiable Dependency: pydantic-settings has 1 known advisory(ies) (CVE-2026-58203 (pydantic-settings: NestedSecretsSettingsSource follows symlinks outside secrets_)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
79% confidence
Finding

The version of pydantic-settings is not fixed, so environments may install a release affected by known security issues without visibility. Since this library handles settings and secrets sources, vulnerable versions could increase the risk of unintended file access or secret handling flaws.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.