Back to skill

Security audit

手势检测

Security checks for vulnerabilities and agentic risk

Overview

This gesture-detection skill mostly does what it claims, but it deserves review because it sends images to an external API, stores an API key in a local .env file, and contains stale Gaokao-related code and instructions.

Install only if you are comfortable sending gesture images or image URLs to XiaoBenYang's remote API and storing the service API key in a local plaintext .env file. Review or remove the stale Gaokao references before trusting the package in a sensitive environment, and prefer a scoped secret store or disposable API key.

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

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill requires environment access, file read/write, and network use to collect and persist an API key and send image data to an external service, but no permissions are declared to inform or constrain that behavior. This creates a transparency and governance gap: users and hosting platforms may not realize the skill can store secrets locally and transmit user-provided images off-platform.

Intent-Code Divergence

Medium
Confidence
89% confidence
Finding
The workflow example references an unrelated function (`search_schools`) in a gesture-detection skill, indicating copy-paste or stale instructions. Such inconsistencies can cause the agent to route requests incorrectly, invoke unintended tools, or mishandle user data, especially in systems that rely on prompt instructions as operational control.

Intent-Code Divergence

Medium
Confidence
84% confidence
Finding
The file mixes gesture-detection behavior with project/workflow text from a different skill context, which weakens the reliability of the operational instructions. In prompt-driven agent systems, this ambiguity can lead to incorrect tool selection, mistaken data handling, or accidental execution paths not intended for this skill.

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
The file configures a Gaokao-related remote service, API endpoint, MCP ID, and credential handling that are unrelated to the declared hand-gesture detection purpose. This scope mismatch is dangerous because it indicates hidden or repurposed functionality and creates a path for unexpected outbound service access and credential use that users would not reasonably expect from an image detection skill.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The skill reads, stores, and returns API credentials through .env, process environment variables, and helper accessors even though such capability is not justified by the stated image-analysis function. This expands the attack surface for secret exposure, misuse by other code paths, and unauthorized persistence of credentials on disk.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The class docstring explicitly labels the component as a Gaokao skill configuration, contradicting the manifest's hand-gesture detection description. While not directly exploitable on its own, this inconsistency is a strong indicator of mislabeled or transplanted code, which raises the likelihood of hidden capabilities and undermines trust in the package's declared behavior.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill processes image URLs or base64 image content through an external API, but it does not warn users that their image data will be transmitted to a third-party service. This lack of notice is risky because images may contain sensitive personal or biometric information, and users cannot give informed consent without clear disclosure.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The code persists API keys into a local .env file without any user-facing notice, consent, or security warning. Storing secrets on disk in plaintext can lead to accidental disclosure through backups, repository commits, local compromise, or subsequent code that reads the same file.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
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}")
Confidence
88% confidence
Finding
Writing the API key into os.environ propagates the secret into process-wide state where it may be consumed by unrelated components, logged, inherited by child processes, or exposed via debugging and crash tooling. In the context of a mislabeled skill, this is more concerning because the secret handling is already outside the expected scope of the advertised functionality.

Credential Access

High
Category
Privilege Escalation
Content
model_config = SettingsConfigDict(
        env_prefix="XBY_GAOKAO_",
        env_file=".env",
        env_file_encoding="utf-8",
        extra="ignore",
    )
Confidence
86% confidence
Finding
Configuring automatic loading from .env enables credential access from local plaintext storage. While reading configuration from .env is common, in this skill it is unjustified by the declared purpose and contributes to secret exposure risk when combined with other code that persists and returns the API key.

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
97% confidence
Finding
The code forcefully reads the .env file and extracts XBY_APIKEY during initialization, independent of the documented settings prefix. This direct secret access bypasses clearer configuration boundaries and indicates deliberate credential harvesting behavior not needed for a hand-gesture detector.

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
97% confidence
Finding
Directly opening and reading the .env file grants the skill access to locally stored secrets beyond normal feature requirements. In a skill whose manifest claims image gesture detection, this kind of credential file access is especially suspicious because it suggests hidden secret collection capability.

Credential Access

High
Category
Privilege Escalation
Content
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
Confidence
93% confidence
Finding
Reading XBY_APIKEY from the environment is a form of credential access that may be legitimate in some applications, but here it is not justified by the advertised purpose and is coupled with manual file parsing and persistence. That combination increases the likelihood of unnecessary secret handling and misuse.

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
96% confidence
Finding
The helper dedicated to saving API keys into .env demonstrates active credential collection and persistence logic. This is risky because it normalizes plaintext secret storage and creates durable artifacts that can be exfiltrated or accidentally shared.

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
95% confidence
Finding
The set_api_key function accepts a raw secret and persists it to .env, reinforcing unnecessary credential handling for a skill that should only detect hand gestures from images. This broadens opportunities for leakage and makes the secret lifecycle harder to audit and control.

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
97% confidence
Finding
The dependency is specified with a lower-bound range instead of an exact version, which makes builds non-reproducible and can silently pull in newer releases with breaking changes or newly introduced supply-chain risk. In a security-sensitive deployment pipeline, this weakens dependency integrity and makes auditing harder.

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
97% confidence
Finding
Using an unpinned version range for pydantic allows environment-dependent resolution and reduces reproducibility across installs. That increases the chance of unintentionally consuming a problematic upstream release and complicates security review and incident response.

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
97% confidence
Finding
An unpinned pydantic-settings dependency permits uncontrolled upgrades at install time, which is a common supply-chain hygiene weakness. Even if not immediately exploitable by itself, it can introduce vulnerable or incompatible code without code changes in this repository.

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
97% confidence
Finding
The python-dotenv requirement is not pinned exactly, so dependency resolution may vary over time and across systems. This creates avoidable supply-chain exposure and makes it harder to ensure that deployed environments match tested ones.

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
96% confidence
Finding
The requirement allows installation of requests 2.31.0, a version with multiple published advisories, so vulnerable code may be pulled into the environment depending on resolver behavior. For an image-processing skill that may fetch remote content or interact with external services, flaws in HTTP handling can expose credentials, weaken request verification, or otherwise increase attack surface.

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
84% confidence
Finding
The requirement permits python-dotenv 1.0.1, which is associated with an advisory involving unsafe file overwrite behavior in set_key when symlinks are followed. This is lower impact here because the file only declares the dependency and the skill context does not itself show dotenv file mutation, but the vulnerable package version is still allowable and should be avoided.

Static analysis

No suspicious patterns detected.