Back to skill

Security audit

图表工具服务

Security checks for vulnerabilities and agentic risk

Overview

This chart skill needs Review because it stores an API key locally and sends it to a configurable third-party service while the documentation is inconsistent about what service it actually uses.

Install only if you trust the Xiaobenyang service and are comfortable storing its API key in a plaintext .env file in the working directory. Prefer a disposable or tightly scoped API key, check that XBY_GAOKAO_BASE_URL points only to the intended provider, and rotate the key if the workspace may have been shared, committed, backed up, or collected.

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

Error
Location
scripts/config.py:11
Finding

Configurable Upstream Endpoint Can Exfiltrate the API Key

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/config.py:45
Finding

API Key Is Persisted in a Plaintext File Without Enforced Access Controls

Content
View full analysis
bool: """Save the API key to 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 ``` ### Technical Analysis The Skill persists the API key in a predictable `.env` file as unencrypted plaintext. `Path.write_text()` is used without explicitly creating the file with owner-only permissions or verifying the permissions and ownership of an existing file. The resulting exposure depends on the process umask and the existing file's mode. In permissive environments, other local users or processes may be able to read the credential. The predictable file location also increases the likelihood of disclosure through source-control commits, workspace collection, backups, diagnostic archives, or unrelated tooling that scans project files. The code also places the secret in the process environment, making it available to code executing within the same process and potentially to child processes launched afterward. ### Attack Path 1. The user provides an API key when prompted by the Skill. 2. `set_api_key()` calls `save_api_key_to_env()`. 3. The API key is written to `.env` in plaintext. 4. The file retains default or preexisting filesystem permi ...[truncated 832 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 (26)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill claims chart-generation functionality but prominently instructs reading and writing a local .env credential named XBY_APIKEY and points users to a non-Quick-Chart provider. In a security context, undocumented credential collection and local secret persistence under a misleading service identity materially increase the risk of credential misuse, accidental exfiltration, and user deception.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill claims chart-generation functionality but prominently instructs reading and writing a local .env credential named XBY_APIKEY and points users to a non-Quick-Chart provider. In a security context, undocumented credential collection and local secret persistence under a misleading service identity materially increase the risk of credential misuse, accidental exfiltration, and user deception.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documentation mixes chart-generation claims with gaokao/school-search naming and examples, indicating copy-paste residue or incomplete repurposing. Such inconsistent identity is a strong security concern because it undermines operator understanding of what the skill actually does and can hide unrelated network calls or business logic behind an innocuous description.

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

This function explicitly writes an API key into a plaintext .env file, creating durable local credential storage that can be exposed through file permissions, backups, debugging artifacts, or accidental repository commits. In a chart tool skill, such secret persistence is not inherently required and therefore increases risk without clear justification.

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

The skill declares no explicit tool scope or permissions despite documented capabilities to read environment state, write configuration, and access the network. That creates an overly broad trust boundary: a reviewer or host cannot easily constrain what the skill may do, and the same document also instructs persistence of user-supplied API keys, increasing the risk of unintended secret handling.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructions and user-facing documentation are entirely in Chinese, and the workflow does not offer any language choice or state that the skill is region-specific. This can violate language/locale policy because it implicitly forces Chinese-language interaction without explicit user opt-in or documented justification.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The workflow says the code only calls APIs for the chart tool, but the example invocation uses an unrelated search_schools function. Contradictory usage examples can cause downstream agents or reviewers to invoke unintended tools or assume capabilities that were not disclosed, which weakens safe tool routing and least-privilege assumptions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The class and function docstrings and the returned/raised user-facing messages are written only in Chinese, including the API key setup error and failure message. This creates a natural-language locale constraint without any opt-in or indication that the skill is intentionally region-specific, which fits the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The module persists an API key to a local .env file and updates process environment state, creating durable secret storage on disk beyond transient runtime use. In a chart-service skill, this expands the trust boundary and increases the chance of credential leakage through local file exposure, backups, repository inclusion, or multi-tenant host access.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The code introduces local secret-storage and environment-mutation capability unrelated to the stated chart-generation purpose. This broadens the skill's capabilities to manage credentials on the host, which can surprise users and create avenues for accidental leakage or misuse of stored API keys.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

Persisting an API key to .env without any user-facing warning or confirmation causes silent long-term storage of a secret on local disk. This is dangerous because users may reasonably expect a provided key to be used only in-memory, not written to files that can later be read, copied, committed, or recovered.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency is specified with a lower bound only, which allows future installs to resolve to different versions over time. This weakens reproducibility and can unintentionally introduce vulnerable or breaking releases into the skill's environment, especially for a network-facing service that relies on HTTP libraries.

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

The manifest does not pin requests, and the package has multiple known advisories across its version history. Because the installed version is not fixed, it is impossible to verify from this file alone whether deployments will receive a safe release, which is risky for a service that communicates with external systems over HTTP.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

Using an unpinned pydantic version means deployments may install different releases depending on timing and resolver behavior. That creates supply-chain and stability risk, and could expose the service to known parser or validation issues present in some versions.

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

pydantic has known advisories, but the requirements entry leaves the exact installed version unresolved. That makes vulnerability status unverifiable and may allow affected versions to be selected in some environments, particularly when rebuilding or deploying later.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The pydantic-settings package is not pinned, so the environment may drift to newly published versions without explicit review. For configuration-handling libraries, this can matter because parsing or secrets-loading behavior changes may introduce security regressions.

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

The pydantic-settings dependency is not pinned despite at least one known advisory affecting some versions. Since this library may load secrets and configuration, leaving the version unresolved increases the chance of deploying an affected release without noticing.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

python-dotenv is declared with a minimum version only, allowing uncontrolled upgrades during installation. Because this package handles local environment files, version drift can expose the skill to file-handling or configuration-related vulnerabilities in affected releases.

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

python-dotenv has known advisories in parts of its release history, but the requirement does not constrain installation to a verified-safe version. In a service that may read local environment files, this creates uncertainty and avoidable supply-chain exposure.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest names and describes a chart tool service for Quick Chart interaction, but the Settings class docstring says this is configuration for '小笨羊高考Skill'. That directly indicates the file's documentation belongs to a different skill context, creating intent/documentation divergence.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The docstrings, comments, and printed error text are written only in Chinese, which can impose a language choice on users or operators without documented opt-in. The file does not indicate that the skill is intentionally region- or language-specific, nor does it offer an alternative language.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.