Back to skill

Security audit

Mermaid文档生成服务

Security checks for vulnerabilities and agentic risk

Overview

This skill is presented as a Mermaid documentation helper, but it asks for and stores a third-party API key locally and contains unrelated Gaokao/XiaoBenYang configuration that users should review before installing.

Install only if you are comfortable giving this skill a XiaoBenYang API key, having that key stored in plaintext in a local .env file, and sending requests through the XiaoBenYang MCP endpoint. Review the leftover Gaokao references and consider requiring a secure secret store, pinned dependencies, and clearer documentation before use.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/config.py:45
Finding

Plaintext Persistence of API Credentials Without Permission Hardening

Content
View full analysis
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 ``` The associated instructions at `SKILL.md:17-19` and `SKILL.md:31` require the agent to ask the user for an API key and persist it through `scripts.config.set_api_key()`. ### Technical Analysis The API key is written in plaintext to `.env` in the current process working directory. `Path.write_text()` does not explicitly enforce owner-only permissions, and the implementation does not use an operating-system credential store, atomic secure-file creation, or explicit permission validation. The path is relative to the current working directory rather than anchored to a controlled configuration directory. The code also does not reject symbolic links. If an attacker can prepare or replace `.env` with a symbolic link under the account running the Skill, the write may target another file writable by that account. Even without that condition, the credential may become accessible to other local users or processes when directory and umask settings are permissive. The same key is placed in the pr ...[truncated 1626 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Unbounded and Unverified Third-Party Dependency Resolution

Content
View full analysis
=2.31.0 pydantic>=2.7.0 pydantic-settings>=2.2.0 python-dotenv>=1.0.1 ``` ### Technical Analysis Every dependency is defined only by a minimum version. There are no exact pins, upper bounds, lock file entries, or package integrity hashes. Consequently, separate installations can resolve to different future releases that were not part of the reviewed artifact. The package names shown are established package names; the audit found no evidence of dependency confusion, typosquatting, or an intentionally malicious package. The risk arises from unconstrained and unverified future resolution: a compromised upstream release, an incompatible release, or an unexpected transitive dependency can enter the environment without a corresponding source review. Installation tools may download packages and execute package build or installation behavior. At runtime, imported dependencies execute with the permissions of the process running the Skill. ### Attack Path 1. A deployment or user installs the project dependencies from `requirements.txt`. 2. The package resolver selects versions newer than those available when the Skill was audited because all constraints are open-ended. 3. An upstream package or transitive dependency has been compromised, maliciously modified, or changed incompatibly. 4. The unreviewed package is installed without hash verification. 5. Malicious package behavior executes during installation, import, or runtime with the permissions of the installing or Skill process. This path depends on a compromised or otherwise unsafe upstream release; no such release was identified in the reviewed project. ### Impact Assessment The maximum impact is bounded by the privileges of the account performing installation or running the Skill. In a compromised-package s ...[truncated 333 chars]
Remediation
View remediation
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)

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill claims to list Mermaid diagrams and fetch documentation, yet analysis indicates it reads and writes API keys in .env, sets environment variables, and manages configuration for an unrelated external service. That combination broadens the attack surface to secret handling and persistence, making the skill far more powerful and risky than advertised.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill claims to list Mermaid diagrams and fetch documentation, yet analysis indicates it reads and writes API keys in .env, sets environment variables, and manages configuration for an unrelated external service. That combination broadens the attack surface to secret handling and persistence, making the skill far more powerful and risky than advertised.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill documentation contains unrelated workflow examples and tooling instructions for gaokao-school APIs inside a Mermaid documentation service. Such cross-domain contamination is a strong sign of copy-paste drift or repurposed logic, which can misroute user requests, cause unintended external calls, and conceal capabilities unrelated to the advertised function.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file for a Mermaid documentation service contains unrelated '高考' service configuration and API-key handling logic, including credential loading and persistence. This kind of scope mismatch is dangerous because it introduces hidden capabilities unrelated to the declared skill purpose, increasing the risk of unauthorized credential handling and supply-chain style abuse.

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

The model_post_init method explicitly reads .env and extracts XBY_APIKEY regardless of the skill's stated Mermaid-doc purpose. In context, this is dangerous because it implements secret harvesting/consumption behavior for an unrelated service, broadening the attack surface and enabling hidden credential use.

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

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill can write an API key to a local .env file and mirror it into process environment variables, which exceeds the reasonable needs of a Mermaid documentation service. Persisting secrets locally creates credential exposure risk through source packaging, backups, logs, filesystem access, or later unintended reuse by other components.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

This function introduces explicit API-key persistence to .env, enabling long-lived storage of secrets on disk. In the context of a Mermaid documentation service, that capability is unnecessary and substantially more dangerous because it can expose credentials to local users, packaged artifacts, backups, or downstream processes.

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

The skill declares no explicit tool scope or permissions even though it appears to use environment access, file read/write, and outbound network capabilities. In an agent setting, missing least-privilege boundaries can let a seemingly simple documentation skill access secrets, persist configuration, and contact external services in ways the user did not expect.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill's user-facing description and operating instructions are entirely in Chinese, with no indication that users may choose another language or locale. Under the policy rule, forcing a specific language without opt-in is a natural-language policy violation unless the locale restriction is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest says the service provides both '列出可用图表' and retrieval of specific chart documentation, yet the only documented tool in the file is scripts.tools.get_diagram_doc. This creates a description-behavior mismatch because the declared scope includes a listing capability that is not represented in the described interface.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documented project structure names a different project, xiaobenyang_gaokao_skill, which contradicts the skill identity and suggests code reuse from another application. This inconsistency increases the risk that the packaged code contains unrelated modules, endpoints, or credential flows that users would not expect from a Mermaid documentation tool.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code retrieves a credential via get_api_key() and transmits it in the XBY-APIKEY header along with params in an outbound POST request. Although the code logs success and error outcomes, it does not provide a user-facing warning, confirmation, or explanatory comment/docstring that user/system data and credentials are being sent to an external API.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Credential persistence occurs silently with no user-facing warning, consent flow, or disclosure that the secret will be written to disk and exported into the process environment. This undermines user expectations and can lead to accidental long-term storage of sensitive secrets in insecure locations.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

The dependency is specified with a lower-bound only (requests>=2.31.0), which allows future unreviewed versions to be installed and also makes builds non-reproducible. This increases supply-chain risk because security posture can change over time and it is impossible to verify exactly which version is deployed.

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

requests has known advisories, but because the manifest does not pin the installed version, it is not possible to verify whether the deployed package is affected. The main risk here is uncertainty: a resolver could install a vulnerable release or drift over time, especially in different environments.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

pydantic>=2.7.0 is unpinned, so installations may resolve to different versions over time. That weakens reproducibility and can silently introduce vulnerable or incompatible releases into the deployment pipeline.

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

pydantic has published advisories, and the lack of exact version pinning prevents verification that the installed version contains necessary fixes. This creates avoidable ambiguity in the dependency security posture and may allow vulnerable versions into deployment.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

Using pydantic-settings>=2.2.0 without an upper bound or exact pin leaves dependency resolution open-ended. This creates uncertainty around what code is actually installed and can expose the project to future vulnerable releases or breaking changes.

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

Because pydantic-settings is unpinned, the project cannot demonstrate whether the installed release is impacted by the cited advisory. Even if the current minimum version is safe, future resolution behavior may still select an affected or otherwise risky version in another environment.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

python-dotenv>=1.0.1 permits any later version, which makes the runtime dependency set unpredictable. In security terms, this is a supply-chain hygiene issue because vulnerable versions may be introduced without explicit review.

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

python-dotenv has known advisories, and the unpinned requirement prevents verification that only a patched release will be installed. This is a low-severity but real supply-chain risk because environments may resolve differently and unintentionally include vulnerable code.

Content

No source excerpt is available for this finding.