Back to skill

Security audit

B站视频信息服务

Security checks for vulnerabilities and agentic risk

Overview

The skill appears intended to retrieve Bilibili data, but it stores a user API key in a local plaintext .env file and contains leftover Gaokao/template references that make the credential scope unclear.

Review this skill before installing. Only provide a Xiaobenyang API key if you are comfortable with it being saved as XBY_APIKEY in a local .env file, and avoid using a high-privilege or reusable key. Check that .env is excluded from source control and restrict file access yourself. The Gaokao/template leftovers should be fixed by the publisher so users can clearly understand what backend and credential scope are involved.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/config.py:45
Finding

API Key Persisted in a Plaintext File Without Enforced Access Restrictions

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 ``` ### Technical Analysis The function stores the user-supplied API key directly in a plaintext `.env` file. The call to `Path.write_text()` does not explicitly create the file with restrictive permissions or correct the permissions of an existing file. For a newly created file, its effective permissions depend on the process umask. For an existing `.env` file, any previously permissive access mode remains in effect. Consequently, the credential may become readable by other local accounts or processes that can access the project directory. Plaintext storage also makes the key susceptible to disclosure through source-control commits, directory archives, workspace synchronization, and backup systems. The key is additionally copied into the process environment. Although required for the current design, this increases exposure to processes or diagnostic facilities that are permitted to inspect that environment. ### Attack Path 1. A user supplies a valid Xiaobenyang API key to ...[truncated 1156 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (31)

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

The documented purpose is Bilibili subtitle/danmaku/comment retrieval, but the behavior includes local .env manipulation, API-key persistence, and references to unrelated 'gaokao' configuration. This mismatch is dangerous because users may grant secrets or trust the skill under false pretenses, while it performs credential-management and potentially unrelated operations outside the declared scope.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The configuration is clearly for an unrelated 'XBY_GAOKAO' service rather than the declared Bilibili video info skill. This kind of capability/context mismatch is dangerous because it can cause the skill to read, store, and transmit credentials for an unrelated backend, increasing the risk of unauthorized data handling or hidden external dependencies.

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

This code manually opens and parses the .env file to extract a specific API key, bypassing normal configuration handling and broadening direct access to locally stored secrets. In the context of a skill whose declared purpose does not justify unrelated credential handling, this increases suspicion and the chance of unintended secret exposure or 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
91% confidence
Finding

The existence check precedes direct reading of the .env file contents, which is part of custom credential extraction logic rather than ordinary feature processing. Because the skill context does not justify harvesting unrelated API credentials, this behavior materially increases the risk of local secret exposure.

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

The code explicitly prioritizes a directly read secret from .env and then overrides it from a separate environment variable, showing active management of a sensitive credential unrelated to the stated Bilibili retrieval role. This secret-handling path can lead to misuse, confusion, and accidental disclosure, especially when naming and prefixes are inconsistent.

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

This function is dedicated to writing an API key into a local .env file, creating durable storage of a secret on disk. Persistent plaintext secret storage is dangerous because it can be exposed through filesystem compromise, shared workspaces, backups, crash reports, or accidental source-control inclusion.

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

The skill advertises capabilities that involve environment access, file read/write, and network use, but it does not declare any tool scope or permission boundaries. This makes it harder to reason about what the skill is allowed to do and increases the risk of over-privileged execution, especially since it also handles credential persistence.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill instructs the model to ask the user for an API key and then save it, but provides no warning about persistence, storage location, retention, or access controls. Collecting secrets without transparent handling guidance increases the chance of credential leakage, accidental reuse, and unsafe storage in plaintext files like .env.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill explicitly instructs the model to collect a user-provided API key and persist it for later use. In this context, that is risky because the skill's overall documentation is inconsistent and template-derived, which raises uncertainty about where the secret is stored and whether it could be reused by unrelated functionality.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The document says code only calls an API, yet elsewhere requires persistent saving of an API key. This contradiction obscures the actual trust boundary and can mislead users and reviewers about sensitive state changes occurring on disk or in environment configuration.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The workflow example references an unrelated school-search tool in a skill that claims to process Bilibili video data. Inconsistent tool references can cause the agent to invoke unintended functionality or mis-handle user input, undermining trust and creating opportunities for accidental data exposure or misuse.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The code mixes pydantic settings with manual .env parsing and uses inconsistent names such as the configured prefix 'XBY_GAOKAO_' versus direct reads of 'XBY_APIKEY'. This inconsistency can cause the wrong secret to be loaded, bypass expected configuration controls, and make security review and secret handling error-prone.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This module persistently stores an unrelated API key in a local .env file even though the stated skill purpose is only retrieving Bilibili subtitles, danmaku, and comments. Unnecessary credential collection and persistence expands the attack surface and can expose secrets through local file disclosure, backups, logs, or repository mishandling.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The function silently writes the provided API key to .env and exports it into the process environment without any user-facing disclosure. Secret persistence without clear consent is risky because users may assume the key is transient while it remains on disk and becomes accessible to other local processes, backups, or accidental commits.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The user-facing docstrings are written entirely in Chinese, and the same pattern repeats across the file, indicating the skill is oriented to a single language without any opt-in or alternative locale handling. Under the policy, forcing a specific language without user choice can be a natural-language locale violation unless clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

This docstring presents the skill behavior only in Chinese, which can impose a language constraint on users or maintainers without an explicit choice. Because no region-specific policy or opt-in is stated in the file, this matches the locale-policy concern defined by SQP-3.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

The natural-language instructions for this function are only in Chinese and do not indicate that the locale is optional or intentionally limited to a specific audience. That can be interpreted as forcing a specific language without user opt-in under the stated policy.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The instruction to directly display raw API response data to the user lacks any filtering or validation step. If the upstream API returns unexpected personal data, tokens, error traces, or malicious content, the skill may expose sensitive information or relay unsafe output verbatim.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The project structure still refers to a 'gaokao' skill template, which indicates the skill may have been repurposed without fully updating its internals. This is a warning sign for hidden functionality or configuration drift that could confuse operators and lead to unintended access patterns.

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, so builds may 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 package like requests.

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, so it is impossible to determine from this file whether the installed version is affected by any known advisory. In a service that retrieves remote content from video URLs, requests is a security-relevant dependency, so unverifiable versioning increases exposure to known upstream flaws.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

Using pydantic>=2.7.0 allows any later version to be installed, which makes deployments non-reproducible and prevents assurance that a reviewed version is actually what runs. Because pydantic has had security issues historically, leaving it unpinned increases supply-chain and patch-management risk.

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

Because pydantic is not pinned, the dependency state cannot be verified against known advisories from the manifest alone. This creates uncertainty around whether input-validation or parsing flaws in upstream versions might be present in deployed environments.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.