Back to skill

Security audit

域名检查服务

Security checks for vulnerabilities and agentic risk

Overview

This skill appears to be a domain-checking tool, but it stores an API key in plaintext and can send that key to a configurable endpoint without strong safeguards.

Review carefully before installing. Only use this if you trust the Xiaobenyang backend and are comfortable with the skill saving your API key in a plaintext .env file in the working directory. Prefer a disposable or tightly scoped API key, avoid running it in shared repositories or shared directories, and inspect any environment variables that could override the API endpoint.

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

API endpoint override permits credential transmission to an attacker-controlled server

Content
View full analysis

Vulnerability Details

File Location: scripts/config.py:12-20; scripts/call_api.py:50-69
Vulnerability Type: Configurable endpoint enabling credential disclosure
Risk Level: High

Vulnerable Code

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

# API配置
base_url: str = "https://mcp.xiaobenyang.com"
mcp_id: str = "1820705335657482"
api_key: str = ""
python
url = f"{settings.base_url}/api"
mcp_id = mcp_id or settings.mcp_id

api_key = get_api_key()
if not api_key:
    raise UpstreamError("API密钥未设置,请先调用 set_api_key()")

headers = {
    "XBY-APIKEY": api_key,
    "func": tool_name,
    "mcpid": mcp_id,
    "Content-Type": "application/json",
}

# data = {k: str(v) if v is not None else "" for k, v in params.items()}

t0 = time.time()
try:
    resp = self._session.post(
        url=url,
        headers=headers,
        data=json.dumps(params),
        timeout=settings.timeout_seconds,
    )

Technical Analysis

The Pydantic settings model uses the XBY_GAOKAO_ environment-variable prefix. Consequently, XBY_GAOKAO_BASE_URL can override the declared base_url. The resulting URL is used without validating its scheme or hostname.

call_tool() then attaches the user's API key to the XBY-APIKEY request header and sends the submitted domain data to that URL. There is no destination allowlist and no explicit requirement that the resolved endpoint use HTTPS.

This issue is exploitable when an attacker can influence the process environment or the settings sources used when the Skill starts. It does not independently grant such access, but it turns configuration influence into disclosure of a subsequently supplied credential.

Attack Path

  1. An attacker capable of controlling the Skill's environment sets XBY_GAOKAO_BASE_URL to an attacker ...[truncated 1042 chars]
Remediation
View remediation

Remediation Suggestions

  1. Make the production API endpoint a non-overridable constant if endpoint customization is unnecessary.
  2. Before transmitting credentials, parse the URL and require:
    • The https scheme.
    • The exact approved hostname mcp.xiaobenyang.com.
    • An expected port and path.
    • No embedded user information.
  3. Reject redirects to unapproved hosts, because an approved initial endpoint could otherwise redirect a credential-bearing request.
  4. If alternate endpoints are required for testing, separate test and production credentials and require an explicit, trusted configuration mode.
  5. Add automated tests verifying that HTTP URLs, unexpected hosts, subdomain lookalikes, and redirect-based destination changes are rejected.
  6. Avoid including credential-bearing headers in requests until destination validation has completed.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/config.py:44
Finding

API key is persisted in a plaintext working-directory file without explicit permission hardening

Content
View full analysis

Vulnerability Details

File Location: scripts/config.py:44-65
Vulnerability Type: Insecure plaintext credential storage
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 user-supplied API key is written verbatim to a .env file relative to the process's current working directory. The code neither selects a dedicated private configuration directory nor explicitly enforces restrictive file permissions.

The effective permissions for a newly created file therefore depend on the runtime environment and process umask. If .env already exists, its existing permissions are retained. A shared or incorrectly configured working directory can consequently expose the key to other local users or processes. A working-directory-relative secret file is also more likely to be included accidentally in source-control commits, build artifacts, archives, or backups.

This is a local credential-exposure issue. Exploitation requires access to the resulting file through filesystem permissions, repository history, backup access, or another process operating in the same workspace.

Atta

...[truncated 1031 chars]

Remediation
View remediation

Remediation Suggestions

  1. Prefer session-only secret handling or an operating-system credential store instead of plaintext persistence.
  2. If persistence is essential, store the secret in a fixed, application-specific user configuration directory rather than the current working directory.
  3. Create the secret file atomically with owner-only permissions, such as mode 0600 on POSIX systems, and verify or correct the permissions of an existing file before writing.
  4. Avoid following symbolic links and use atomic replacement to reduce link and race-related risks.
  5. Add .env to version-control ignore rules and secret-scanning controls, while recognizing that ignore rules do not replace filesystem protection.
  6. Inform the user before persisting the credential and provide a way to use an environment variable or ephemeral input without saving it.
  7. Document credential rotation and deletion procedures in case the file is 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 (28)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill claims to check domain registration status, but documentation indicates it reads and writes a local .env API key, persists external credentials, and configures unrelated service parameters such as gaokao defaults. This expands the trust boundary from a narrow lookup tool into a credential-handling integration, increasing risk of secret misuse, unexpected data exfiltration, or deceptive permission requests.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill claims to check domain registration status, but documentation indicates it reads and writes a local .env API key, persists external credentials, and configures unrelated service parameters such as gaokao defaults. This expands the trust boundary from a narrow lookup tool into a credential-handling integration, increasing risk of secret misuse, unexpected data exfiltration, or deceptive permission requests.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The configuration clearly targets an unrelated XBY/Gaokao service rather than a domain registration checker, including mismatched env prefix, default service URL, and service identifiers. In this skill context, that mismatch is a strong indicator of repurposed or misbound code that could route requests and credentials to the wrong backend, creating substantial data exposure and supply-chain risk.

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

This code forcibly reads XBY_APIKEY from .env outside the standard settings framework, creating a hidden credential access path that operators may not expect. In the context of an unrelated domain-checking skill, custom secret scraping increases risk because it broadens credential collection behavior beyond the declared function.

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
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 persists an API key to a plaintext .env file, creating a durable credential artifact on disk. In the context of a skill whose stated purpose does not clearly require secret retention, this expands the attack surface substantially because the key may be exposed through filesystem access, backups, logs, or accidental source control inclusion.

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 even though it appears to require environment access, file read/write, and network capabilities. In an agent setting, missing scope declarations weaken least-privilege controls and can allow a broader-than-expected attack surface for credential persistence, local file modification, and outbound requests.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The skill instructions and user-facing documentation are written entirely in Chinese and present the interaction flow as mandatory, without indicating that users may choose another language. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless a justified locale restriction is documented.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The workflow and example code reference gaokao/school-search tool calls instead of domain-check operations, showing that the document may have been copied from another skill without proper adaptation. Security-relevant documentation inconsistencies can mislead operators, cause incorrect tool invocation, and hide the real data flows or capabilities of the skill.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This code contains user-facing/docstring text such as "小笨羊MCP API客户端", "调用小笨羊MCP工具", and the runtime error "API密钥未设置,请先调用 set_api_key()", all in Chinese. Because the file provides no opt-in, fallback, or documented justification that the skill is China/Chinese-specific, this appears to enforce a specific language in violation of the locale-choice policy.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The code bypasses the declared Pydantic settings mapping by manually reading XBY_APIKEY from .env and os.environ, while the configured prefix implies a different canonical naming scheme. This inconsistency can cause operators to place secrets under unexpected names, increase misconfiguration risk, and hide credential flows from normal configuration review.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill includes persistent API key storage in .env even though the stated purpose is domain registration checking, which typically does not justify secret collection and persistence without clear user need. In context, the mismatch between stated functionality and credential-handling behavior makes the capability more suspicious because it enables long-lived secret retention beyond a transient runtime need.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The function writes the provided API key directly into a local .env file and updates the process environment without any confirmation, warning, or disclosure. This is dangerous because it silently converts a transient secret into a persistent local artifact that may be committed, backed up, or read by other tooling on the host.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

项目结构部分将工程目录写为 xiaobenyang_gaokao_skill/,而整个技能其余部分宣称是域名检查服务。这种文档标识与当前技能用途不符,说明文档意图和实际技能身份存在混杂,可能误导维护者或调用方。

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency specification for requests uses a lower-bound range instead of an exact pinned version, which makes builds non-reproducible and can allow installation of unexpectedly vulnerable or breaking releases. In a network-facing domain-checking service, this increases supply-chain uncertainty because HTTP behavior and security fixes depend on whichever version is resolved at install time.

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

The manifest does not pin requests, and the package has multiple known advisories, so there is no way to verify from this file whether deployments are using a safe release. In a service that likely performs outbound HTTP requests, this uncertainty is more relevant because requests is a directly exposed component in network interactions.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The pydantic dependency is not pinned to an exact version, so deployments may resolve to different releases over time. That weakens reproducibility and can expose the service to known parser/validation vulnerabilities or regressions depending on what gets 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
84% confidence
Finding

Because pydantic is unpinned and has published advisories, the actual security posture of the deployed validator/parser cannot be determined from the manifest alone. This is dangerous because input validation libraries are often on the trust boundary, and vulnerable versions can turn untrusted input into denial of service or validation bypass conditions.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

Using pydantic-settings with only a minimum version allows future installs to pick different releases, including ones with newly introduced flaws or incompatible behavior. Because configuration parsing often touches secrets and environment-derived values, version drift can have security consequences.

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

The unpinned pydantic-settings dependency means the project could install a version affected by a known advisory without any indication in the manifest. Given that settings libraries may read secrets or filesystem-backed configuration, uncertainty around vulnerable versions is a meaningful supply-chain risk even if no exploit is shown here.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

python-dotenv is also specified as an unbounded minimum version, which can lead to inconsistent dependency resolution and accidental uptake of vulnerable releases. Since this package commonly reads local configuration and secrets, insecure versions may affect confidentiality or file handling safety.

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

python-dotenv has known advisories, and without a pinned version the file does not establish whether an affected release may be installed. Since dotenv tooling can read and modify local configuration files, vulnerable versions may introduce file overwrite or unsafe path-handling risks in environments where those features are used.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
72% confidence
Finding

The natural-language description in the class docstring is only in Chinese and gives no indication that the user can choose another language or locale. Under the stated policy, forcing a specific language without opt-in can be a locale-policy issue.

Content

No source excerpt is available for this finding.