Back to skill

Security audit

植物识别

Security checks for vulnerabilities and agentic risk

Overview

This plant-identification skill uses a third-party API in a purpose-aligned way, but users should understand that their API key is saved locally and submitted images are sent to the provider.

Install only if you are comfortable giving this skill a Xiaobenyang API key, storing that key in a local .env file, and sending plant images or image URLs to Xiaobenyang for analysis. Avoid using sensitive photos, private/internal image URLs, or credentials you cannot revoke.

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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (16)

Lp3

Medium
Category
MCP Least Privilege
Confidence
85% confidence
Finding
The skill declares no permissions while its documented behavior clearly involves reading environment/config state, writing an API key to persistent storage, and making external network requests. This mismatch undermines informed consent and security review because users and platforms cannot accurately assess what the skill will access or transmit.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill instructs the agent to ask the user for an API key and save it via `scripts.config.set_api_key(api_key)` without warning about storage location, retention, access scope, or security handling. Collecting credentials in-band and persisting them without clear disclosure increases the risk of accidental exposure, misuse, or insecure storage.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill accepts either image URLs or base64-encoded image content and sends that data to an external plant-recognition API, but it does not disclose this transfer to the user. User images can contain sensitive personal or location information, so failing to provide a privacy warning prevents informed consent and can lead to unintended data exposure.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The code persists the API key in a plaintext .env file and also exports it into the process environment, increasing the number of places where the secret can be exposed through local file access, backups, logs, child processes, or debugging tools. There is no indication of secure storage, permission hardening, or user warning/consent around credential persistence.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The function sends a user-supplied image URL to an external API via call_api, but this file provides no explicit disclosure, consent mechanism, or data-handling warning. Because images and their source URLs may contain sensitive personal or location-related information, silent third-party transmission creates a real privacy and data-governance risk.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
This function transmits raw base64-encoded image content to an external API without any warning in the code path shown. Directly sending image bytes is especially sensitive because the payload may contain faces, documents, metadata, or other private information, and users may not realize their content leaves the local environment.

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
75% confidence
Finding
The code bypasses normal settings handling and forcefully reads the .env file to extract XBY_APIKEY, creating custom secret-parsing logic that may ignore expected controls and normalize plaintext secret storage. In a skill/plugin context, this makes credential access more dangerous because the component is explicitly designed to locate and ingest secrets from local disk.

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
75% confidence
Finding
Checking for .env existence as part of a forced credential read supports the same insecure pattern of local plaintext secret retrieval. Although not malicious on its own, in this skill context it contributes to a workflow where the module actively seeks credentials from disk rather than requiring safer provisioning.

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
88% confidence
Finding
This function is explicitly dedicated to saving an API key into a plaintext .env file, which creates long-lived local secret exposure. In a reusable agent skill, that is more dangerous because secrets may remain on disk across runs, be copied with the project, or be accessible to other local users or tooling.

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
86% confidence
Finding
The function's documented purpose is to set and persist the API key, reinforcing insecure credential retention as an intended feature. That makes the skill more dangerous than a normal config reader because it encourages users to deposit secrets into a predictable local file for future use.

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
92% confidence
Finding
The dependency is specified with a lower bound only (`requests>=2.31.0`), which allows future installs to resolve to different versions over time. This weakens build reproducibility and can unintentionally introduce vulnerable or incompatible releases through the software supply chain.

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
90% confidence
Finding
`pydantic>=2.7.0` is unpinned, so installations are not reproducible and may pull in unexpected future versions. This increases supply-chain risk and can cause security or stability regressions without code changes in the skill itself.

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
90% confidence
Finding
`pydantic-settings>=2.2.0` is also specified as a minimum version only, permitting uncontrolled upgrades at install time. This creates a supply-chain exposure and undermines reproducibility for deployments of the skill.

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
91% confidence
Finding
`python-dotenv>=1.0.1` is unpinned, allowing arbitrary newer releases to be installed later. That is a dependency hygiene weakness because future versions may introduce vulnerabilities or behavioral changes without review.

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
95% confidence
Finding
The requirements allow installation of `requests` 2.31.0, and the scanner reports multiple advisories affecting that version. In a skill likely to make outbound HTTP requests for plant identification, a vulnerable HTTP client can expose credentials, weaken TLS/session verification behavior, or otherwise increase the attack surface when handling untrusted URLs or remote resources.

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 requirements permit `python-dotenv` 1.0.1, which is flagged for a symlink-following arbitrary file overwrite issue in `set_key`. This is only exploitable if the skill uses the affected write path or modifies `.env` files in a context where an attacker can influence filesystem links, so the practical risk here appears limited but real.

Static analysis

No suspicious patterns detected.