Back to skill

Security audit

Markdown转Notion转换器

Security checks for vulnerabilities and agentic risk

Overview

This skill is not clearly malicious, but it needs Review because it stores an API key, sends Markdown to a remote service, and contains unrelated Gaokao-service leftovers.

Install only if you are comfortable sending Markdown content to the xiaobenyang remote API and storing XBY_APIKEY in a local .env file. Use a scoped or disposable API key if possible, keep .env out of version control, and treat the unrelated Gaokao references as a reason to inspect the package carefully before use.

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
90% confidence
Finding
The skill declares no permissions while its documented behavior requires environment access, local file read/write, and outbound network access. This hidden capability increases the risk of secret collection and exfiltration because users and hosting platforms are not given an accurate security boundary up front.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The advertised function is Markdown-to-Notion conversion, but the skill also instructs the agent to collect an API key, read local configuration, persist secrets to .env, and call an external third-party service. This mismatch is dangerous because users may provide sensitive credentials under the assumption of a simple local format conversion, while the skill actually expands trust to local secret storage and remote transmission.

Intent-Code Divergence

High
Confidence
93% confidence
Finding
The documentation contains a gaokao/school-search example workflow unrelated to Markdown conversion, indicating copy-paste errors and confused operational guidance. In a security context, such inconsistencies reduce trustworthiness and can cause the agent to invoke the wrong tools or request irrelevant sensitive inputs, increasing the chance of misuse or accidental data exposure.

Intent-Code Divergence

Medium
Confidence
90% confidence
Finding
The documented project structure references a gaokao-related project name instead of the declared Markdown-to-Notion converter, which suggests the package may be repurposed or misdocumented. This weakens provenance and auditability, making it harder to verify what code will actually run and whether hidden functionality is present.

Description-Behavior Mismatch

High
Confidence
93% confidence
Finding
This file exposes a generic remote API client that can invoke arbitrary upstream tools via attacker-controlled or caller-controlled `tool_name`, `mcp_id`, and `params`, which is broader than the advertised Markdown-to-Notion conversion purpose. That capability mismatch is dangerous because it can hide unexpected remote execution paths, data exfiltration, or access to unrelated MCP functions behind a seemingly narrow document-conversion skill.

Context-Inappropriate Capability

Medium
Confidence
82% confidence
Finding
The code performs external network requests to a configurable upstream service for a skill presented as a local Markdown-to-Notion converter, creating an unexpected trust boundary. If abused, sensitive document contents and metadata in `params` may be transmitted to an external endpoint, and the generic API design increases the chance of unauthorized remote actions beyond simple format conversion.

Description-Behavior Mismatch

High
Confidence
96% confidence
Finding
The configuration file is materially inconsistent with the stated purpose of a Markdown-to-Notion converter: it contains gaokao-service branding, a hardcoded remote base URL, an MCP ID, and logic to read/write API credentials. That mismatch is a strong supply-chain red flag because users may grant trust or secrets to a skill whose actual behavior and integration surface are unrelated to its advertised function.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
Persisting API credentials to a local .env file is risky for a tool described as a content-format converter because users would not reasonably expect secret storage side effects. Secrets written to project directories are commonly exposed through source control, backups, logs, or other local processes, increasing the chance of credential leakage.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The code writes the provided API key to both .env and the process environment immediately, without any confirmation, warning, or transparency to the user. This creates a stealthy persistence path for sensitive credentials and can surprise operators who intended only to perform a transient conversion task.

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
89% confidence
Finding
The post-init hook forcibly reads XBY_APIKEY from .env regardless of the advertised Markdown-conversion purpose. In this context, secret-loading behavior is broader than users would expect and increases the chance of handling or exposing credentials unrelated to the converter's stated function.

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
89% confidence
Finding
Creating a direct Path to .env as part of custom secret-reading logic is part of the same unnecessary credential access path. In a skill that should primarily transform Markdown, this adds hidden secret-handling behavior and broadens the trusted surface without clear justification.

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 is explicitly designed to save an API key into .env, creating secret persistence on disk. In the context of a purported Markdown-to-Notion converter, such credential storage is unexpected and increases the risk of accidental disclosure through repository commits, local compromise, or operational misconfiguration.

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 setter persists the API key to .env as part of normal operation, coupling secret storage to a simple configuration update. This is dangerous because it silently converts a transient secret into long-lived local state in a skill whose declared purpose does not clearly justify credential persistence.

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 dependency is specified with a lower bound only, so future installs may resolve to different versions over time. This weakens reproducibility and can unintentionally introduce vulnerable or breaking releases through the supply chain, even if the current line is not directly malicious.

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 version for pydantic makes builds non-reproducible and allows unexpected upstream changes to enter the environment. In a server component, this increases supply-chain risk and can lead to accidental adoption of insecure or incompatible releases.

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
An unpinned pydantic-settings dependency permits silent drift in resolved versions across environments. That can expose the project to newly introduced vulnerabilities or behavioral changes without any code change 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
95% confidence
Finding
The python-dotenv requirement is not pinned, so deployments may pick different versions depending on install time and resolver behavior. For configuration-handling libraries, this can create avoidable supply-chain and stability risk in an MCP server context.

Known Vulnerable Dependency: requests==2.31.0 — 3 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)

Low
Category
Supply Chain
Confidence
89% confidence
Finding
The dependency range allows installation of requests 2.31.0, which has published advisories including credential leakage via malicious URLs and session verification issues. In an MCP server that may fetch remote content or interact with APIs, this is more dangerous because attacker-controlled URLs or network interactions could trigger those flaws under the right code paths.

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
83% confidence
Finding
The allowed version python-dotenv 1.0.1 is reported as vulnerable to a symlink-following issue in set_key that may permit arbitrary file overwrite in affected usage patterns. Because this skill is a server component that may manage configuration files in deployment environments, the issue could matter if the vulnerable API is used on attacker-influenced paths.

Static analysis

No suspicious patterns detected.