Back to skill

Security audit

菜谱查询工具

Security checks for vulnerabilities and agentic risk

Overview

This recipe skill appears functional, but it asks for an API key and stores/sends it in ways that need review before installation.

Review this skill before installing. Only use an API key you are comfortable storing in a local .env file, check that .env will not be committed or shared, and avoid running it where untrusted environment variables or .env contents could redirect the API endpoint.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (3)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/config.py:10
Finding

Configurable API Endpoint Can Redirect and Expose the API Key

Content
View full analysis

Vulnerability Details

File Location: scripts/config.py:10-18, scripts/call_api.py:51-67
Vulnerability Type: Credential exposure through an unvalidated configurable endpoint
Risk Level: Medium

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

SettingsConfigDict allows base_url to be overridden through the XBY_GAOKAO_BASE_URL environment variable or the configured .env source. The client then constructs a URL from this value and transmits the API key in the XBY-APIKEY request header.

No validation restricts the URL to HTTPS or to an approved hostname. Consequently, a party capable of influencing the process environment or configuration can direct authenticated requests to an arbitrary server. A plaintext HTTP endpoint could additionally expose the credential to network observers.

Attack Path

  1. An attacker gains the ability to influence the Skill's environment or configuration source.
  2. The attacker sets XBY_GAOKAO_BASE_URL to an attacker-controlled URL, such as https://attacker.example.
  3. A user invokes get_all_dishes or `get_dish_co ...[truncated 680 chars]
Remediation
View remediation

Remediation Suggestions

  • Keep the service endpoint fixed in code when runtime endpoint customization is unnecessary.
  • If customization is required, parse the URL and require the https scheme, the expected port, and an explicit allowlist of approved hostnames.
  • Reject URLs containing user information, unexpected ports, IP literals, or ambiguous host representations.
  • Disable redirects for authenticated requests or validate every redirect destination before forwarding sensitive headers.
  • Separate endpoint configuration from untrusted .env or process settings in production.
  • Add tests verifying that HTTP URLs, unapproved domains, and redirect-based credential forwarding are rejected.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/config.py:44
Finding

API Key Is Persisted in a Plaintext Project File

Content
View full analysis

Vulnerability Details

File Location: scripts/config.py:44-65
Vulnerability Type: Insecure plaintext storage of sensitive credentials
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 stores the API key directly in .env as plaintext. It uses Path.write_text() without explicitly creating the file with restrictive permissions. Effective access therefore depends on ambient filesystem permissions and the process umask.

The file is located relative to the current working directory rather than a dedicated protected credential location. This increases the chance that the secret is exposed to other local users or processes, included in backups, copied with the project, or accidentally committed to version control.

Attack Path

  1. A user supplies a valid API key as required by the Skill workflow.
  2. set_api_key() calls save_api_key_to_env().
  3. The key is written in plaintext as XBY_APIKEY=<secret> to .env in the current working directory.
  4. Another local process or user with read access, a backup collector, or a repository operation ob ...[truncated 537 chars]
Remediation
View remediation

Remediation Suggestions

  • Prefer session-only credential handling or an operating-system credential store instead of plaintext project files.
  • Obtain explicit user consent before persisting a credential.
  • If file persistence is unavoidable, store the key in a dedicated user configuration directory outside the project.
  • Create the credential file atomically with owner-only permissions such as 0600; verify and correct permissions on existing files before use.
  • Ensure .env is excluded from version control, packaging, logs, diagnostics, and backups where appropriate.
  • Avoid replacing files non-atomically. Write to a securely created temporary file in the same protected directory and then atomically replace the destination.
  • Support credential revocation and rotation, and advise users to rotate any key suspected of exposure.

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Dependencies Use Open-Ended Version Constraints

Content
View full analysis

Vulnerability Details

File Location: requirements.txt:1-4
Vulnerability Type: Non-reproducible and insufficiently constrained third-party dependencies
Risk Level: Low

Vulnerable Code

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

Technical Analysis

All dependencies use open-ended minimum-version constraints. A future release from the configured package index can therefore be selected automatically without having been reviewed with this project. The absence of exact versions and package hashes also prevents reproducible dependency resolution and artifact-integrity verification.

This does not establish that any currently listed package or release is malicious. It creates supply-chain exposure by allowing future compromised, incompatible, or unexpectedly changed releases to enter a build automatically.

Attack Path

  1. A later dependency release satisfies one of the open-ended >= constraints.
  2. That release is compromised, malicious, or contains a security regression, or the configured package index is tampered with.
  3. A new installation resolves and downloads the unreviewed release.
  4. Package installation or subsequent imports execute the dependency's code with the privileges of the installing or running process.
  5. The resulting impact depends on the behavior of the compromised dependency and the privileges of that process.

Impact Assessment

A compromised dependency could potentially access API credentials, application data, files available to the process, and outbound network resources. It would execute with the same operating-system privileges as the installer or Skill runtime. The finding represents increased supply-chain risk rather than evidence that the currently declared dependencies contain malicious code.

Remediation
View remediation

Remediation Suggestions

  • Generate and commit a reviewed lock file containing exact transitive dependency versions.
  • Require cryptographic hashes for downloaded artifacts, for example through a hash-locked requirements file and pip --require-hashes.
  • Install packages only from an approved HTTPS package index.
  • Use automated dependency vulnerability scanning and controlled update reviews.
  • Rebuild the lock file periodically so security updates are adopted intentionally rather than through unrestricted resolution.
  • Test dependency updates in an isolated environment before production deployment.
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 (30)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill is presented as a recipe tool, but it instructs the agent to read and persist API keys in local configuration and references unrelated gaokao-oriented configuration. Secret collection plus local persistence under a misleading description creates a substantial risk of over-collection, improper storage, and use of credentials outside the declared purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill is presented as a recipe tool, but it instructs the agent to read and persist API keys in local configuration and references unrelated gaokao-oriented configuration. Secret collection plus local persistence under a misleading description creates a substantial risk of over-collection, improper storage, and use of credentials outside the declared purpose.

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
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 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
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

This function explicitly saves an API key into a plaintext .env file, creating a local credential exposure risk. In the context of a recipe-query skill, this is more suspicious because credential persistence is not obviously necessary and could mislead users into storing sensitive tokens unnecessarily.

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 declares no explicit tool scope or permission boundaries even though it appears to rely on environment access, file reads/writes, and network calls. Without a declared allowlist, an agent may be induced to use broader capabilities than users expect, increasing the attack surface for credential handling and outbound requests.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill name and entire user-facing description are presented only in Chinese, and the document provides no option for another language or explanation that the skill is restricted to a Chinese-language or region-specific audience. This can constitute a language/locale policy violation when the skill effectively forces a specific language without user opt-in.

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 ask the user for an API key and persist it via configuration, but it does not warn the user that the credential will be stored locally or explain retention and handling. This can lead to uninformed disclosure of secrets and unnecessary persistence of sensitive data in plaintext-style configuration files.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The example invocation references a school-search function unrelated to recipe lookup, indicating copy-paste residue and possible hidden or unintended capabilities. In security-sensitive agent skills, such inconsistencies can cause the model to call the wrong function family or suggest a broader backend than declared.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code sends request data to an upstream service and includes an API key in headers, which is a safety-relevant network operation under the missing-warning rule. While internal logging exists for errors and success, there is no user-facing prompt, print, comment, or docstring warning that params and credentials-related metadata will be transmitted externally.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

技能清单将该技能描述为通过命令行查询菜谱和报菜名的工具,但这里的代码不仅做查询配置,还提供了将 API key 写入 .env 文件并更新进程环境变量的持久化凭据管理能力。这种凭据写入/管理并不是“菜谱查询”这一用途下显而易见的用户可见功能,超出了描述所传达的范围。

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This skill persists an API key into a local .env file even though that capability appears unnecessary for a simple recipe query tool. Storing secrets on disk increases the chance of credential exposure through repo commits, backups, shared workspaces, or local file disclosure, especially when users are not clearly informed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The function writes the provided API key directly to .env without any warning, confirmation, or visibility into persistence behavior. Users may unknowingly leave long-lived credentials on disk where other local processes, users, or accidental commits can expose them.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The project structure still contains gaokao-skill identifiers, which suggests the skill may be repurposed from another project without a full security and functionality review. While not directly exploitable by itself, this inconsistency weakens trust and raises the chance of latent unrelated code paths, endpoints, or secrets handling remaining in the package.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency is specified with only a lower bound, so builds may resolve to different versions over time and can silently pick up vulnerable or breaking releases. In a requirements file, this weakens supply-chain reproducibility and makes it impossible to verify whether a safe version of requests is consistently installed.

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

requests has known security advisories, and because the manifest does not pin a version, there is no reliable way to determine whether installations are affected. This is dangerous as a supply-chain verification gap: a deployment could resolve to a vulnerable version and the risk would not be visible from the manifest alone.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

Using pydantic>=2.7.0 without an upper bound or exact pin allows environment-dependent resolution and reduces reproducibility. That creates supply-chain risk because future installs may bring in a vulnerable or incompatible version without any manifest change.

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

pydantic has published advisories, but the version range here is too loose to verify safety. That uncertainty is itself a security weakness because different environments may install different versions, including ones with denial-of-service or parsing flaws.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

An unpinned pydantic-settings dependency means the installed version is not deterministic across environments or over time. This increases exposure to newly introduced vulnerabilities and makes incident response and SBOM validation harder.

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

Because pydantic-settings is not pinned, the project cannot demonstrate that deployed versions are outside known advisory ranges. For a tool likely to load configuration and secrets, unverifiable dependency state raises the risk of configuration or filesystem-related issues if a vulnerable release is installed.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

python-dotenv is also left unpinned, which permits uncontrolled dependency drift. Even if the current minimum version is safe, future resolution can select a release with security regressions or behavior changes affecting secret handling.

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

python-dotenv has advisories related to file handling, and the absence of version pinning makes it impossible to tell whether the project will install an affected release. Since dotenv libraries often process local configuration and secrets, this uncertainty can matter if the package is used in write or load paths involving attacker-controlled files.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The class docstring uses Chinese-only wording, and additional user-visible exception/messages in the file are also Chinese-only, indicating a fixed language choice. The policy requires avoiding forced language/locale behavior unless the user is given a choice or the locale restriction is clearly documented and justified.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.