Back to skill

Security audit

智能搜索工具集

Security checks for vulnerabilities and agentic risk

Overview

The skill is a mostly coherent search helper, but it requires and persistently stores an API key in a plaintext working-directory `.env` file and has some inconsistent documentation.

Review this skill before installing if you are not comfortable giving a XiaoBenYang API key to it. Use a low-privilege/revocable key, avoid entering proprietary or secret search terms, and remove or rotate the key if it may have been written to `.env` in a shared or source-controlled directory.

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:44
Finding

API Key Persisted in a Plaintext Working-Directory File Without Enforced Access Controls

Content
View full analysis

Vulnerability Details

File Location: scripts/config.py, lines 44-64
Vulnerability Type: Plaintext credential storage with uncontrolled file permissions
Risk Level: Medium

Vulnerable Code

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

Technical Analysis

The function persistently writes the user-provided API key in plaintext to .env, resolved relative to the process's current working directory. It does not enforce restrictive permissions, verify that the destination is a regular file rather than a symbolic link, use atomic file replacement, or ensure that the destination is outside a source-controlled project.

The resulting file permissions depend on the operating system and process umask. In a permissive environment, another local account or process may be able to read the credential. Because the path depends on the working directory, the secret may also be placed in an unrelated project and subsequently exposed through source-control commits, backups, indexing services, or shared workspaces.

Persisting the credential is not the minimum privilege necessary to make an authenticated API request. Session-only credential ...[truncated 1567 chars]

Remediation
View remediation

Remediation Suggestions

  1. Do not persist the key by default. Keep it in memory for the active session and request explicit, informed consent before any cross-session storage.
  2. Prefer an operating-system credential manager such as Windows Credential Manager, macOS Keychain, or a Linux Secret Service provider.
  3. If file storage is unavoidable, use a dedicated per-user configuration directory rather than the current working directory.
  4. Create the credential file with owner-only permissions (0600) using secure low-level creation flags, and verify permissions after creation.
  5. Reject symbolic links and verify that the destination is a regular file owned by the expected user.
  6. Write through a securely created temporary file and atomically replace the destination to reduce race conditions and partial writes.
  7. Ensure .env and equivalent secret files are excluded from source control, packaging, diagnostics, and backups where appropriate.
  8. Avoid copying the key into os.environ unless subprocess inheritance is explicitly required; the reviewed implementation does not require subprocess access.
  9. Provide a credential-removal function and document key rotation and revocation procedures for users whose keys 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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (29)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The file references configuration and project structure for an apparently unrelated 'gaokao' codebase while presenting itself as a technical search skill. This kind of cross-domain inconsistency is dangerous because it suggests copy-pasted or repurposed logic, which can hide unintended endpoints, misroute secrets, or invoke services unrelated to the user's request.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The file references configuration and project structure for an apparently unrelated 'gaokao' codebase while presenting itself as a technical search skill. This kind of cross-domain inconsistency is dangerous because it suggests copy-pasted or repurposed logic, which can hide unintended endpoints, misroute secrets, or invoke services unrelated to the user's request.

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

The code explicitly reads the .env file and extracts XBY_APIKEY, which is credential handling beyond normal typed settings loading and can normalize insecure plaintext secret use. In the context of a technical search tool, this secret-reading logic is somewhat off-scope and increases concern because it directly processes credentials from disk.

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

Constructing a Path to .env as part of explicit credential retrieval supports direct access to locally stored secrets. While not exfiltration on its own, it contributes to insecure secret-handling design by encouraging plaintext local credential storage and manual parsing.

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

This function is explicitly designed to save an API key into a plaintext .env file, which creates a real credential exposure risk if the file is leaked, synced, backed up, or committed. Given the skill is described as a search toolkit, credential persistence to local disk is more dangerous because it is not obviously necessary for core functionality.

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

The skill declares no explicit tool scope or allowed-tools despite instructing use of environment access, persistent file writes (.env/config), and network/WebFetch. In a skill ecosystem, missing capability boundaries increases the chance of overbroad execution and makes it harder to audit whether credential handling and outbound requests are actually necessary.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The documentation introduces mandatory API-key collection and persistent configuration even though the skill is described as a search URL tool. Hidden credential dependencies increase the risk of unnecessary secret collection and storage, especially when users are not clearly told why the key is needed and what remote service receives it.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill instructs the agent to ask the user for an API key and save it, but gives no warning about sensitive credential handling, storage duration, access controls, or who can later read the stored secret. This creates a meaningful risk of secret exposure, over-collection, and user consent failure.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The workflow explicitly requires collecting a user-provided API key and persistently storing it. Persistent storage of secrets in simple config files or .env is risky because such files are often broadly readable, accidentally committed, or reused across unrelated skills and sessions.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill says tools return search URLs that should then be fetched via WebFetch, but later says the tool returns raw API JSON that should be shown directly to users. Contradictory data-flow documentation makes it unclear whether content comes from third-party pages or an upstream API, which impairs consent, review, and safe handling of untrusted external content.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The instructions direct WebFetch to third-party search URLs but do not warn that user queries may be transmitted to external services such as search engines or community sites. For technical searches, queries may still contain proprietary code snippets, incident details, or internal project names, so undisclosed transmission creates privacy and confidentiality risk.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The module persists an API key into a local .env file and environment variables, creating credential exposure risk on shared systems, in backups, or if the file is accidentally committed. For a search-tool skill, local secret persistence is not strictly required and expands the attack surface beyond the advertised functionality.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Saving a supplied API key to .env without any user-facing confirmation can cause users to unknowingly leave long-lived credentials on disk. This is dangerous because local plaintext secret storage may be harvested by other users, malware, backup systems, or source-control mistakes.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The docstrings and operational guidance in this code are presented exclusively in Chinese, and the same pattern continues throughout the file for all tool descriptions. This creates a language-policy issue because the skill effectively forces a specific language/locale for understanding and use, without any opt-in or alternative language support.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill name, description, and operational instructions are presented entirely in Chinese and do not offer users a language or locale option. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation unless the restriction is clearly justified.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The workflow example uses scripts.tools.search_schools(...), and the project structure names the repository xiaobenyang_gaokao_skill, which conflicts with the rest of the document describing a technical search toolkit with ai_search_* functions. These references actively point to a different intent/domain and undermine confidence that the code and documentation align.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

The dependency is specified with a lower-bound only (requests>=2.31.0), which permits installation of different future versions across environments and makes builds non-reproducible. In a security-sensitive tool that performs network operations, this also makes it harder to verify whether a deployed version includes known fixes or introduces new vulnerable behavior.

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

The manifest does not pin requests, and the package has multiple known advisories, so the actual installed version cannot be verified as safe from the file alone. This is more concerning in a smart search tool because requests is likely used for outbound HTTP operations, where issues like credential leakage, redirect handling, or TLS/session flaws can directly affect users and secrets.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

Using pydantic>=2.7.0 leaves the actual installed version unconstrained above the minimum, reducing reproducibility and preventing reliable assurance about which security fixes are present. Because this package handles validation and settings, version drift can affect both security posture and runtime behavior.

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

pydantic has known advisories, but because the dependency is not pinned, the resolved version is unverifiable and may be vulnerable. The risk is somewhat contextual here: as a validation library it is less exposed than a network client, but parsing attacker-controlled input could still trigger denial-of-service or parsing flaws in affected versions.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

pydantic-settings>=2.2.0 is unpinned, so installations may resolve to different versions over time, making the environment difficult to audit and potentially exposing deployments to newly introduced or unpatched issues. Since this library influences configuration loading, dependency uncertainty can affect secret and settings handling.

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

The unpinned pydantic-settings dependency prevents determining whether the installation includes fixes for known issues. Given that settings libraries may read secrets and configuration from files or environment sources, a vulnerable version could affect configuration integrity or secret boundaries depending on how the skill is deployed.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

python-dotenv>=1.0.1 allows any later version, which weakens reproducibility and makes it impossible to determine from the manifest alone whether the deployed package is affected by future or past advisories. Because dotenv libraries interact with local configuration and secrets, version ambiguity can have security consequences.

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

Static analysis

No suspicious patterns detected.