Back to skill

Security audit

注册服务搜索工具

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to be a real MCP registry search helper, but it stores a user API key in plaintext and can send that key to a configurable API endpoint, so it needs review before installation.

Install only if you trust the publisher and are comfortable providing a XiaoBenYang API key. Prefer using a temporary or low-privilege key, check that .env is not committed or shared, and verify that XBY_GAOKAO_BASE_URL cannot be changed to an untrusted endpoint before using the skill.

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

Error
Location
scripts/config.py:11
Finding

Configurable API Endpoint Can Redirect and Disclose Credentials

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/config.py:43
Finding

API Key Is Persisted in Plaintext Without Enforced Restrictive Permissions

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 except Exception as e: print(f"保存API key失败: {e}") return False ``` ### Technical Analysis The complete API key is written as plaintext to `.env`. `Path.write_text()` does not explicitly establish owner-only permissions; access is determined by existing file permissions and the process umask. On systems with a permissive umask, a newly created file may be readable by other local users. If `.env` already exists with broad permissions, rewriting it does not correct those permissions. Keeping the secret in the project working directory also increases the possibility that it will be included in source-control commits, workspace archives, backups, or artifact bundles. ### Attack Path 1. The user provides an API key through the documented setup workflow. 2. `set_api_key()` calls `save_api_key_to_env()`. 3. The function writes `XBY_APIKEY=<secret>` to `.env` in plaintext. 4. The resulting file inherits permissions from the existing file or the process umask. 5. Another local principal or a workspace collection process reads the file. 6. ...[truncated 572 chars]
Remediation
View remediation
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 (26)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill claims to perform registry search, but it also reads local .env files, modifies environment variables, and persists API keys and other configuration values. Secret collection and local configuration mutation are materially more sensitive than search, and the mismatch can lead to unjustified credential harvesting or unintended persistence on the host.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill claims to perform registry search, but it also reads local .env files, modifies environment variables, and persists API keys and other configuration values. Secret collection and local configuration mutation are materially more sensitive than search, and the mismatch can lead to unjustified credential harvesting or unintended persistence on the host.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documentation says this is an MCP registry search tool, but the project structure and examples reference unrelated gaokao/school search code. Such cross-domain inconsistency is a strong signal that the skill may be mislabeled, copied from another project, or hiding behavior not apparent from the declared purpose, which undermines trust and safe review.

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 custom model_post_init force-reads .env to extract XBY_APIKEY outside normal settings handling, which unnecessarily broadens secret-processing logic. This increases the chance of mishandling credentials, bypassing expected configuration controls, and normalizing direct secret scraping from workspace files.

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

Opening and reading the .env file to manually parse an API key creates direct plaintext secret access in application code. In the context of a search tool, this is unnecessary secret-handling behavior and increases the risk of accidental leakage or abuse if the code path is triggered unexpectedly.

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

This function is explicitly designed to persist an API key to a local .env file, creating durable plaintext storage of a secret. In a skill whose declared role is service search, this capability is unnecessarily dangerous because it can expose credentials to other local users, accidental commits, backups, and compromised tooling.

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

The skill advertises executable capabilities that include environment access, file read/write, and network use, but it does not declare any explicit tool scope or permission boundaries. In an agent setting, this increases the chance of over-broad execution and makes it difficult to constrain sensitive operations such as reading or persisting secrets.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill instructs the agent to ask the user for a third-party API key and persist it, even though simple registry search does not obviously justify credential collection. In this context, requesting and storing secrets expands the attack surface and creates risk of credential misuse, leakage, or collection under misleading pretenses.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill implements persistent API key storage and mutation logic in a local .env file, which exceeds the stated purpose of a server search tool and creates unnecessary secret-handling capability. Expanding a simple search skill to write credentials increases the attack surface and can expose secrets through local file access, backups, logs, or other tooling that reads .env files.

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 both write a credential to disk and modify the process environment, capabilities that are not directly proportional to a search-only tool. Such secret-writing behavior can lead to unintended persistence, lateral exposure to other local components, and makes compromise of the host or workspace more valuable to an attacker.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Persisting an API key to a local .env file without any explicit warning or confirmation can surprise users and leaves sensitive material on disk. Secrets stored this way may be leaked through source-control mistakes, local backups, shared workspaces, or other tools that inspect environment files.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency specification uses a lower-bound version constraint rather than pinning to an exact version, which makes builds non-reproducible and can result in different environments resolving to vulnerable or incompatible releases. In a network-facing tool that relies on HTTP requests, this increases supply-chain and patch-management uncertainty even though the file itself does not prove active exploitation.

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

The manifest does not pin requests, and the package has multiple known advisories across its release history, so it is not possible to verify from this file alone that deployed environments will avoid affected versions. In a search tool likely making outbound HTTP requests, requests is operationally relevant, which makes unverifiable version selection a meaningful supply-chain risk.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

Using an unpinned pydantic version allows installation of any later release that satisfies the minimum bound, reducing reproducibility and making it hard to verify whether known vulnerable versions are excluded. This is a supply-chain hygiene issue rather than direct malicious behavior in the skill content.

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

Because pydantic is not pinned, the file does not establish whether installed versions avoid known advisories such as regex DoS or date parsing issues. This is especially relevant for tools that may parse user-controlled input or configuration, where vulnerable parsing behavior can become reachable.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

The unpinned pydantic-settings dependency means downstream installs may pull in different releases over time, including versions with security defects or breaking changes. For configuration-loading libraries, that uncertainty can affect secret handling and environment parsing behavior.

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

The pydantic-settings package has known advisory history, and without an exact version it is impossible to confirm whether the deployed build includes a fixed release. Since settings libraries may read secrets or filesystem-backed configuration, unresolved version ambiguity can matter in real deployments.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

python-dotenv is declared with only a minimum version, so environments may resolve to different package versions with different security properties. Because dotenv libraries often interact with local configuration files and secrets, lack of pinning increases exposure to supply-chain and configuration-related risk.

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

python-dotenv has known advisories and is not pinned here, so the security posture of installed environments cannot be verified from the manifest. Given that dotenv tooling can read and modify local environment files, vulnerable versions may affect secret integrity or local file safety if those features are used.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The class docstring is written only in Chinese, and other user-facing strings in the file are also Chinese-only. This can violate a language/locale policy when a skill is expected to be language-neutral or user-selectable but does not provide any opt-in or alternative locale handling.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The raised error message "API密钥未设置,请先调用 set_api_key()" is user-facing natural language and forces a specific language without any opt-in or locale negotiation. This is a policy concern if the skill should support broader audiences or respect user language preferences.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The function docstring and returned error message "API调用失败" are natural-language outputs exposed to callers, but they are fixed to Chinese with no documented locale restriction or user choice. That can violate organizational language policy for multilingual or default-English environments.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

Settings 类的文档字符串写的是“小笨羊高考Skill配置”,而当前技能清单名称和描述均指向MCP注册服务搜索。该内联文档反映出代码来源于不同用途的技能,和当前代码意图说明存在明显不一致。

Content

No source excerpt is available for this finding.