Back to skill

Security audit

图表生成工具

Security checks for vulnerabilities and agentic risk

Overview

This chart skill wraps a remote API but stores an API key in plaintext and contains mismatched school-search/MinIO packaging details, so it needs review before installation.

Install only if you are comfortable sending chart data to XiaoBenYang's remote API and storing the service API key in a local .env file. Avoid sensitive chart inputs, keep .env out of source control, and prefer a version that documents the external data flow, validates the API host, and uses safer secret storage.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/config.py:45
Finding

API Key Persisted in a Plaintext Environment File

Content
View full analysis

Vulnerability Details

File Location: scripts/config.py:45-63
Vulnerability Type: Plaintext storage of sensitive credentials
Risk Level: Medium

The Skill instructions at SKILL.md:17-18 and SKILL.md:34 direct the agent to collect an API key from the user and persist it through scripts.config.set_api_key(). The following implementation stores that credential directly in .env:

python
def save_api_key_to_env(api_key: str) -> bool:
    """Store the API key in the .env file."""
    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"Failed to store API key: {e}")
        return False

Technical Analysis

The API key is written as an unencrypted string to a predictable file in the process's current working directory. Path.write_text() uses the process's normal file-creation behavior and umask; the code does not explicitly enforce owner-only permissions, use a protected credential store, or perform an atomic secure file creation.

The predictable filename also increases the likelihood that the credential will be included in source-control commits, directory archives, backups, diagnostics, or copied workspaces. The implementation additionally places the key in the process environment, where it may be accessible to other code running with sufficient local pri ...[truncated 1009 chars]

Remediation
View remediation

Remediation Suggestions

  • Prefer an operating-system credential manager, secret-management service, or session-only secret injection instead of persistent plaintext storage.
  • If file persistence is unavoidable, create the credential file atomically with owner-only permissions such as 0600, and verify its ownership and permissions before reading it.
  • Store secrets in a dedicated credential file rather than rewriting a general-purpose .env file.
  • Add .env and all credential-file variants to source-control ignore rules and distribution exclusions.
  • Warn users explicitly before persisting the credential and provide a session-only option.
  • Implement credential revocation and rotation guidance for users who may have exposed an existing .env file.
  • Avoid placing the credential in the process environment unless required, and minimize its lifetime in memory.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/call_api.py:55
Finding

Environment-Controlled API Endpoint Can Receive the User's API Key

Content
View full analysis

Vulnerability Details

File Location: scripts/config.py:11-20; scripts/call_api.py:55-76
Vulnerability Type: Credential exfiltration through an insufficiently validated configurable endpoint
Risk Level: Medium

The application defines its destination through a Pydantic settings model whose fields can be populated with the XBY_GAOKAO_ environment-variable prefix:

python
class Settings(BaseSettings):
    """XiaoBenYang Skill configuration."""

    model_config = SettingsConfigDict(
        env_prefix="XBY_GAOKAO_",
        env_file=".env",
        env_file_encoding="utf-8",
        extra="ignore",
    )

    # API configuration
    base_url: str = "https://mcp.xiaobenyang.com"
    mcp_id: str = "1820705335657482"
    api_key: str = ""

The resulting URL is then used without an HTTPS or hostname allowlist before the API key is attached to the request:

python
url = f"{settings.base_url}/api"
mcp_id = mcp_id or settings.mcp_id

api_key = get_api_key()
if not api_key:
    raise UpstreamError("API key is not configured; call set_api_key() first.")

headers = {
    "XBY-APIKEY": api_key,
    "func": tool_name,
    "mcpid": mcp_id,
    "Content-Type": "application/json",
}

t0 = time.time()
try:
    resp = self._session.post(
        url=url,
        headers=headers,
        data=json.dumps(params),
        timeout=settings.timeout_seconds,
    )
    resp.raise_for_status()

Technical Analysis

Because Settings uses env_prefix="XBY_GAOKAO_", the base_url field can be overridden through XBY_GAOKAO_BASE_URL. The request code trusts the resulting value and attaches the user's XBY-APIKEY header to it. No validation requires the https scheme, the expected mcp.xiaobenyang.com hostname, an approved port, or an approved final redirect destination.

This creates a credential-confused endpoint condition: a party capable of influencing the pr ...[truncated 1607 chars]

Remediation
View remediation

Remediation Suggestions

  • Do not permit the authenticated production API origin to be overridden in normal operation.
  • If configurability is required, parse the URL and enforce an explicit allowlist of approved HTTPS hostnames and ports before attaching credentials.
  • Reject non-HTTPS schemes, embedded URL credentials, malformed hosts, unexpected ports, IP-literal bypasses, and unapproved subdomains.
  • Disable cross-origin redirects or validate every redirect destination before forwarding the API key.
  • Separate test and production clients so test endpoint configuration cannot receive production credentials.
  • Apply the same destination validation to values obtained from environment variables and .env files.
  • Inform users that chart parameters are transmitted to a remote service and advise them not to submit unnecessary sensitive data.
  • Rotate any API key that may have been sent to an untrusted endpoint.
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 (30)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The documentation claims Apache ECharts/MinIO functionality, but the detected behavior centers on reading and persisting API credentials and managing a different remote service domain, with no substantiated chart or MinIO implementation. This kind of deceptive or inaccurate packaging can conceal data exfiltration paths and causes users to provide secrets under false pretenses.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The documentation claims Apache ECharts/MinIO functionality, but the detected behavior centers on reading and persisting API credentials and managing a different remote service domain, with no substantiated chart or MinIO implementation. This kind of deceptive or inaccurate packaging can conceal data exfiltration paths and causes users to provide secrets under false pretenses.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The documentation claims Apache ECharts/MinIO functionality, but the detected behavior centers on reading and persisting API credentials and managing a different remote service domain, with no substantiated chart or MinIO implementation. This kind of deceptive or inaccurate packaging can conceal data exfiltration paths and causes users to provide secrets under false pretenses.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The API-key onboarding ties the skill to an external '小本羊' service even though the skill is presented as a local chart-generation utility. That context makes the issue more dangerous because it conditions the agent to collect credentials and send data off-platform without clear user expectations.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The workflow and example invocation reference a different 'gaokao/school search' routing skill (search_schools) while the surrounding document presents an ECharts charting tool. This strong inconsistency suggests copied or repurposed instructions and undermines trust in what code or remote actions the skill may actually perform.

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

The model_post_init method forcibly reads .env content manually to extract XBY_APIKEY, bypassing the normal typed settings flow and expanding direct secret-file handling in application code. In the context of an unrelated chart tool, this secret-harvesting behavior is suspicious and increases the risk of undocumented credential collection and misuse.

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

Opening and reading the .env file directly gives this module raw access to all local secret content, even though it only later extracts one key. In a skill whose declared purpose is chart generation, direct secret-file access is more dangerous because it is not clearly tied to the advertised functionality.

Content

Scanner excerpt · scripts/config.py (reported line 32)May include surrounding context.

python
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():

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

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

This function is explicitly designed to persist an API key into a .env file on disk. Storing secrets in workspace files can lead to credential leakage through file permissions, accidental commits, backups, or access by other tools and users on the same system.

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 tool scope or permission boundaries even though its documented behavior includes environment access, file reads/writes, and network use. In an agent setting, missing explicit scope increases the chance of over-broad execution and makes it harder for users or the platform to understand what the skill can access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill instructs the agent to solicit an API key and persist it via set_api_key(api_key) but gives no notice about where it will be stored, how long it will be retained, or who can access it. In agent environments, silent credential persistence creates avoidable secrecy and account-compromise risk.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documentation instructs the model to call search_schools, but the listed tools only define chart-generation functions. Contradictory invocation guidance can cause the agent to route to unintended capabilities or reveal that the skill bundle was stitched together from unrelated components without adequate review.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill tells the agent to directly display raw external API output to the user. Unfiltered third-party responses may contain unexpected content, prompt-injection text, sensitive data, or misleading instructions, especially since the skill already relies on a remote service outside the declared charting context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code retrieves a credential via get_api_key() and sends it in the XBY-APIKEY header during a network request. Although the code has internal logging for request outcomes, there is no confirmation prompt, user-facing warning, or explanatory comment/docstring disclosing that credentials and request data will be sent to an external API.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The configuration class docstring refers to an unrelated '高考Skill' while the manifest describes a chart-generation tool. This mismatch is a strong integrity red flag because it suggests code reuse from another skill or undeclared functionality, which makes security review and user consent less reliable.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file manages and persists an external API credential for 'XBY'/'gaokao'-related access that is not justified by the chart-generation skill description. Undeclared credential handling increases the chance of hidden data flows, accidental exfiltration, or user deception about what external services the skill contacts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code writes the provided API key directly into a local .env file and updates process environment state without any confirmation, warning, or storage protections. Persisting secrets this way can expose credentials to other local users, backups, source-control mistakes, or downstream tooling that reads the workspace.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The tool forwards caller-supplied chart data and configuration to an external API via call_api(...), but this file provides no disclosure, consent flow, or data-classification guardrails. In a charting/data-analysis skill, users may supply sensitive business metrics or personal data, so silent transmission to a remote service can create privacy, compliance, and data-handling risk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
72% confidence
Finding

The skill is named and primarily instructed in Chinese, while substantial invocation and parameter guidance is provided in English, and there is no statement offering the user a language preference or opt-in. This can amount to an implicit language policy choice that may not match the user's locale or accessibility needs.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% 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 makes it difficult to verify whether a vulnerable or incompatible release of requests could be pulled into the environment.

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

Requests has multiple published advisories, but the manifest does not pin a specific version, so it is impossible to determine from this file whether a safe release will be installed. In a tool that may fetch remote resources or interact with storage services, uncertainty around HTTP client security increases supply-chain and runtime exposure.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

Using only a minimum version for pydantic means dependency resolution is non-deterministic and may select newer vulnerable or breaking releases. This creates supply-chain risk and prevents reliable auditing of the exact package version in use.

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

Pydantic has known advisories, and because the requirement is not pinned, the effective installed version cannot be verified from the manifest alone. This leaves uncertainty about exposure to denial-of-service or parsing-related flaws, especially in a tool that likely processes user-supplied chart or configuration data.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The unpinned pydantic-settings requirement permits uncontrolled version drift across environments. That makes security posture unverifiable and can expose the application to future vulnerable releases without code 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

Static analysis

No suspicious patterns detected.