Back to skill

Security audit

野生动物检测

Security checks for vulnerabilities and agentic risk

Overview

This skill appears to be an API-backed wildlife detector, but it stores the user's API key in a local plaintext .env file and contains stale unrelated school-search references that make the package scope unclear.

Review before installing. Use a dedicated XiaoBenYang API key with limited quota if possible, assume submitted images are sent to the external service, and avoid saving valuable credentials in this project directory unless you accept plaintext .env storage. Rotate the key if the workspace is shared, archived, or committed.

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
scripts/config.py:45
Finding

API Key Persisted in a Plaintext Environment File

Content
View full analysis

Vulnerability Details

File Location: scripts/config.py:45-63, 70-78
Vulnerability Type: Plaintext sensitive-data storage
Risk Level: Medium

The Skill automatically persists a user-supplied API key to a plaintext .env file. The relevant code is:

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()
        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
    except Exception as e:
        print(f"保存API key失败: {e}")
        return False


def set_api_key(api_key: str) -> bool:
    """设置API key并持久化到.env"""
    if not api_key or not api_key.strip():
        return False
    api_key = api_key.strip()
    if not save_api_key_to_env(api_key):
        return False
    # 更新全局 settings 实例
    settings.api_key = api_key
    return True

Technical Analysis

save_api_key_to_env() writes the credential directly into .env as XBY_APIKEY=<secret>. The file is created or replaced using Path.write_text() without explicitly applying owner-only permissions, checking whether the destination is a symbolic link, using atomic replacement, or integrating with a protected credential store.

Consequently, protection depends on the process umask and surrounding directory permissions. The credential can also be exposed if the project directory is copied, archived, bac ...[truncated 1706 chars]

Remediation
View remediation

Remediation Suggestions

  1. Prefer session-only credential handling through a protected environment variable rather than automatically persisting the key.
  2. If persistence is necessary, obtain explicit user consent and use an operating-system credential manager or secret-management service.
  3. If a file must be used, create it with owner-only permissions such as 0600; verify the resulting permissions before storing the key.
  4. Resolve the destination against a trusted application directory rather than the ambient working directory.
  5. Reject symbolic links and non-regular files, and perform the update through a securely created temporary file followed by an atomic replacement.
  6. Ensure .env is excluded from version control, packaging, backups, diagnostics, and logs.
  7. Avoid retaining the key in more process-global locations than necessary, and never include it in exception messages or diagnostic output.
  8. Document credential revocation and rotation procedures for users whose .env file may have been exposed.
Vulnerability Patterns
  • 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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (27)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill claims to process images for wildlife detection, yet the documented code responsibilities center on reading and persisting API credentials, configuring remote service parameters, and managing generic service access. In this context, credential storage and broad remote configuration without clear image-processing boundaries substantially increase the risk of misuse and make the skill more dangerous than its benign description suggests.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill claims to process images for wildlife detection, yet the documented code responsibilities center on reading and persisting API credentials, configuring remote service parameters, and managing generic service access. In this context, credential storage and broad remote configuration without clear image-processing boundaries substantially increase the risk of misuse and make the skill more dangerous than its benign description suggests.

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",
    )

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code explicitly reads from and writes to a local .env file to manage an API key, even though local secret persistence is not justified by the stated wildlife-detection purpose. Storing secrets in plaintext on disk increases exposure to accidental disclosure, theft by other local processes, source control leaks, or reuse by unintended components.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
92% confidence
Finding

This code force-reads a local .env file specifically to extract XBY_APIKEY, adding custom credential harvesting behavior beyond normal configuration loading. In the context of a wildlife-detection skill, this is unjustified and increases the risk of covert secret collection and misuse.

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

The explicit existence check and subsequent read of .env are part of manual secret extraction logic. This broadens the skill’s access to local sensitive configuration files, which is especially concerning given the mismatch between the advertised wildlife-detection purpose and the credential management behavior.

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

This line shows the code overriding configuration with a directly fetched environment variable containing an API key. Accessing sensitive credentials may be legitimate in some applications, but here it is not well justified by the skill description and contributes to unnecessary credential-handling capability.

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

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill is presented as a wildlife image detection tool, yet this module includes functionality to set, persist, and retrieve unrelated API credentials. That mismatch is risky because it expands the skill’s capabilities into credential handling without a clear need, creating an unnecessary avenue for secret collection and local persistence.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

This function is dedicated to saving an API key into .env, creating persistent plaintext credential storage on local disk. That materially increases the blast radius of any local compromise, accidental repository inclusion, backup exposure, or cross-component secret reuse.

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

The skill declares no explicit tool scope or permission boundaries despite requiring environment access, file read/write, and network capabilities. In an agent setting, missing least-privilege declarations increases the chance that the skill can access or persist sensitive data, including API keys, beyond what users would reasonably expect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs the agent to request an API key from the user and persist it via configuration, but provides no warning about storage, retention, access controls, or privacy implications. In an agent environment this is dangerous because users may disclose secrets without informed consent, and the key may be written to disk or exposed to other processes.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The workflow documentation references an unrelated school-search function in a wildlife-detection skill, indicating copy-paste errors or poor maintenance. Such contradictions are security-relevant because they undermine trust in the documented behavior and suggest the routing layer may invoke unintended tools or services with user input.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The docstring identifies the module as a different '高考' skill while the declared skill is wildlife detection, which is a strong indicator of code reuse or intent mismatch. Such inconsistency undermines trust and suggests the module may perform functions unrelated to its advertised purpose, increasing the chance of hidden or unnecessary behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The function silently persists an API key into .env and updates the process environment without any user-facing warning or informed consent. This is dangerous because users may believe they are providing a transient credential while the software actually stores it in plaintext for future use.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The project structure block labels the package as xiaobenyang_gaokao_skill, which refers to a different domain than wildlife detection. While this may be a copy-paste artifact, it is still intent-documentation that contradicts the skill's declared purpose and can confuse maintainers or agents about what codebase they are using.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

The dependency specification for requests uses a lower-bound only constraint, which allows installation of newer unreviewed versions or older vulnerable versions within resolver behavior across environments. This weakens build reproducibility and makes it impossible to reliably determine whether known security fixes are present.

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

requests has known advisories, and because the manifest does not pin a version, there is no reliable way to verify whether the installed release is affected. In a skill that likely performs network calls for image handling or inference, an unsafe HTTP client version could increase exposure to credential leakage or TLS-related issues.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The pydantic dependency is unpinned, so different environments may resolve to different releases with different security properties. That creates supply-chain uncertainty and may expose the skill to known issues if a vulnerable release is installed.

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

pydantic has known advisories, but the unpinned requirement means the deployed version cannot be verified as patched. If the skill parses untrusted inputs or configuration, a vulnerable parser/validator version could enable denial of service or other unsafe behavior.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

Using an unpinned pydantic-settings version prevents reproducible builds and makes it unclear whether deployed instances include security fixes for known advisories. This is a supply-chain hygiene issue even if no vulnerable version is currently confirmed.

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

pydantic-settings has a known advisory and the current manifest does not establish whether a safe version will be installed. Because settings libraries can read secrets and filesystem-backed configuration, version ambiguity can matter if hostile files or symlinks are present in the runtime environment.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

python-dotenv is specified with only a minimum version, so installs are not deterministic and may pull versions with differing security behavior. For configuration-related packages, version uncertainty can be risky because they often interact with files and environment secrets.

Content

Scanner excerpt · requirements.txt (reported line 4)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: python-dotenv has 2 known advisory(ies) (CVE-2026-28684 (python-dotenv: Symlink following in set_key allows arbitrary file overwrite via ); CVE-2026-28684 (python-dotenv reads key-value pairs from a .env file and can set them as environ)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
91% confidence
Finding

python-dotenv has known advisories, and without version pinning the deployment may resolve to an affected release. Since dotenv tooling reads or writes environment files, vulnerable versions may create risk around file overwrite or symlink handling in certain operational setups.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

This file contains natural-language strings such as the class and function docstrings and error messages entirely in Chinese, including the returned failure message. The policy only permits locale constraints when the skill offers language choice or clearly documents a justified regional restriction, which is not evident in this file.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

Natural-language strings and comments indicate the skill is defined specifically in Chinese, but this file does not state that the user can choose another language or that the locale restriction is an intentional, documented regional constraint. Under the language/locale policy, forcing a specific language without opt-in can be a policy issue.

Content

No source excerpt is available for this finding.