Back to skill

Security audit

万智牌卡牌查询服务

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to provide card lookup functionality, but it also stores API keys in a local .env file and exposes an unrelated image-composition tool that is not clearly disclosed by its stated purpose.

Review this skill before installing. Only use it if you are comfortable with it reading and writing a local .env file for an API key, and consider using a restricted throwaway API key. The publisher should clearly document credential storage, pin or lock dependencies, and either remove or separately disclose the unrelated hzls image feature.

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 (19)

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill documentation instructs behavior that uses environment access, local file read/write, and network calls, but it does not declare corresponding permissions. This undermines least-privilege review and can cause users or hosting platforms to grant or tolerate broader capabilities than they knowingly approved, especially when paired with credential handling and external API access.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The declared purpose is a MTG card query MCP server, but the documented behavior includes local secret persistence, reading environment and .env state, an unrelated image-generation feature, and what appears to be a client wrapper around an external service rather than a server. This mismatch is dangerous because it obscures actual data flows and capabilities, making it easier to smuggle in sensitive operations or unexpected exfiltration under an innocuous description.

Description-Behavior Mismatch

Medium
Confidence
80% confidence
Finding
The documented 'hzls' image-composition feature is outside the stated scope of a card information query/search service. Scope creep increases attack surface because users may enable or trust the skill for simple lookup tasks while it also performs additional content-processing operations that can involve unexpected remote calls or resource usage.

Intent-Code Divergence

Medium
Confidence
85% confidence
Finding
The project structure and examples repeatedly reference a different 'gaokao' skill and unrelated function names, which indicates copy-paste inconsistency and weak change control. In security terms, this raises the risk that the documented interface does not match the real code path, causing reviewers and users to misunderstand what code executes and what data is handled.

Description-Behavior Mismatch

Medium
Confidence
91% confidence
Finding
The module provides functionality to persist and mutate API credentials in a local .env file even though the stated skill purpose is only card lookup/search. This expands the trust boundary unnecessarily and creates a secret-handling surface that can expose credentials through local file access, backups, logs, or accidental inclusion in source control.

Context-Inappropriate Capability

Medium
Confidence
89% confidence
Finding
Embedding local secret-management capability in a card-query skill is unnecessary for the advertised behavior and creates avoidable credential exposure risk. Writing secrets into .env on disk makes them accessible to other local processes, accidental commits, and endpoint compromise.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The skill metadata says it provides card information query/search, but the code also exposes `hzls`, which generates composite images from arbitrary user-supplied text. This is a scope mismatch that can bypass user/operator expectations, policy review, or permission gating, and it expands the attack surface from read-only lookup to content generation.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill directs the agent to ask the user for an API key and save it via local configuration without warning about storage location, retention, masking, or consent. This is dangerous because user-supplied secrets may be written to disk or environment state in plaintext, exposed to other tools/processes, or retained longer than the user expects.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The code stores API keys to .env without any user-facing warning, confirmation, or indication of persistence. Users may believe they are supplying a transient credential, while the skill silently leaves a durable secret on disk that can later be exposed or reused.

Credential Access

High
Category
Privilege Escalation
Content
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")
Confidence
92% confidence
Finding
The code explicitly force-reads .env to extract a specific API key outside the normal settings abstraction. This creates direct credential-access logic that is unnecessary for a simple query skill and increases the chance of mishandling, unintended reuse, or hidden secret collection behavior.

Credential Access

High
Category
Privilege Escalation
Content
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():
Confidence
92% confidence
Finding
Opening and reading the .env file directly to search for XBY_APIKEY is explicit credential access logic. In the context of a card-information service, this behavior is out of scope and enlarges the attack surface for local secret exposure and stealthy secret handling.

Credential Access

High
Category
Privilege Escalation
Content
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()
Confidence
94% confidence
Finding
This function exists specifically to persist an API key into .env, creating a durable local secret store inside the skill. That is unnecessary for the advertised card-query functionality and increases the risk of credential disclosure through source control mistakes, file theft, or multi-user systems.

Credential Access

High
Category
Privilege Escalation
Content
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()
Confidence
93% confidence
Finding
The set_api_key function normalizes and then persists user-supplied credentials to disk, turning secret input into long-lived local state. For a card query/search skill, this is disproportionate to its stated purpose and creates unnecessary opportunities for credential leakage.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.31.0
pydantic>=2.7.0
pydantic-settings>=2.2.0
python-dotenv>=1.0.1
Confidence
96% confidence
Finding
The dependency is specified with a lower bound only, which allows future installs to resolve to different versions over time. This weakens build reproducibility and can unexpectedly introduce vulnerable or incompatible releases into the service's runtime.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.31.0
pydantic>=2.7.0
pydantic-settings>=2.2.0
python-dotenv>=1.0.1
Confidence
95% confidence
Finding
Using an unpinned pydantic version means dependency resolution can drift between environments and over time. That increases supply-chain risk and may pull in a later vulnerable release without code changes.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.31.0
pydantic>=2.7.0
pydantic-settings>=2.2.0
python-dotenv>=1.0.1
Confidence
95% confidence
Finding
A minimum-only version constraint for pydantic-settings permits uncontrolled upgrades during installation. This can lead to non-reproducible deployments and accidental inclusion of vulnerable dependency versions.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.31.0
pydantic>=2.7.0
pydantic-settings>=2.2.0
python-dotenv>=1.0.1
Confidence
95% confidence
Finding
The unpinned python-dotenv requirement allows any newer version to be installed, which undermines deterministic builds. In a server-side MCP service, this increases supply-chain and operational risk because dependency behavior may change unexpectedly.

Known Vulnerable Dependency: requests==2.31.0 — 5 advisory(ies): 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); CVE-2026-25645 (Requests has Insecure Temp File Reuse in its extract_zipped_paths() utility func) +2 more

Medium
Category
Supply Chain
Confidence
98% confidence
Finding
The requirements allow installation of requests 2.31.0, a version with published advisories including credential leakage and TLS/session verification issues. Because this skill is an MCP server that likely makes outbound HTTP requests for card lookup, vulnerable HTTP client behavior is directly relevant and can expose secrets or weaken transport security when interacting with attacker-influenced URLs or redirects.

Known Vulnerable Dependency: python-dotenv==1.0.1 — 1 advisory(ies): CVE-2026-28684 (python-dotenv: Symlink following in set_key allows arbitrary file overwrite via )

Low
Category
Supply Chain
Confidence
86% confidence
Finding
The allowed python-dotenv 1.0.1 version has an advisory related to symlink following in set_key, which can enable arbitrary file overwrite in workflows that modify .env files. This appears less central for a read-oriented query service, so exploitability depends on whether the application or its tooling ever calls set_key on attacker-influenced paths.

Static analysis

No suspicious patterns detected.