Back to skill

Security audit

越南股市数据服务

Security checks for vulnerabilities and agentic risk

Overview

This looks like a Vietnam market-data wrapper, but it stores an API key in plaintext and contains leftover Gaokao identifiers that make the backend and credential scope unclear.

Install only if you are comfortable giving this skill a Xiaobenyang API key and having it stored in plaintext in a local .env file. Prefer using a limited or disposable API key, inspect or remove the stale Gaokao identifiers, pin/update dependencies, and delete the saved .env entry when you no longer need the skill.

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

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill documentation instructs the agent to read configuration, write a user-supplied API key to local storage, and call external network services, yet no explicit permissions are declared. This creates a transparency and governance gap: operators and users may believe the skill is read-only market data access when it can also persist secrets and access the network.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The declared purpose is a Vietnam stock data service, but the documented behavior includes persistent credential storage and reliance on an upstream generic Xiaobenyang API platform, with even the project structure referencing an unrelated gaokao skill. This mismatch impairs informed consent and trust boundaries, making it easier for users to disclose secrets to a skill whose actual backend and storage behavior are not accurately represented.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
A market-data skill is documented as saving a user-provided API key locally, which exceeds the expected scope of a read-only data retrieval tool. Persisting secrets introduces unnecessary retention risk, including later leakage through logs, backups, local file disclosure, or unintended reuse by other processes.

Context-Inappropriate Capability

Medium
Confidence
92% confidence
Finding
The documentation adds durable credential storage to a simple quote/query workflow without demonstrating necessity. That design broadens the attack surface because compromise of the local environment or workspace now exposes reusable API credentials, not just transient query data.

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
The configuration clearly targets a different service and domain than the declared Vietnam stock data skill: it uses a Gaokao-prefixed environment namespace, a different base URL, and mismatched identifiers. This kind of identity/configuration mismatch can route credentials and requests to the wrong backend, causing data leakage, unintended access, or users trusting a skill that is actually wired to another service.

Intent-Code Divergence

Medium
Confidence
94% confidence
Finding
The docstring says this is configuration for a different skill, contradicting the advertised Vietnam stock service. While a docstring alone is not exploitable code, in this file it reinforces a broader service-identity mismatch that can mislead reviewers and users about what backend is actually being used.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The code persists the API key into a local .env file automatically, without any consent flow, warning, or storage-hardening. Persisting secrets in plaintext increases exposure to accidental commit, local compromise, multi-user system access, or downstream tooling that reads workspace files.

Ssd 3

Medium
Confidence
96% confidence
Finding
The instruction to save a user-provided API key creates a clear data retention risk because secrets remain on disk beyond the immediate task. In context, this is more dangerous because the skill is presented as a data-query utility, so users may not expect their credential to be stored locally and reused later.

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
86% confidence
Finding
This code forcibly reads the .env file manually to extract XBY_APIKEY, bypassing normal settings behavior and broadening secret access inside the skill. In the context of a mislabeled skill pointing at a different service, explicit secret extraction increases the risk that credentials are silently consumed for an unexpected backend.

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
86% confidence
Finding
Checking for and reading the .env file directly is part of a custom secret extraction path that is unnecessary and increases exposure of local credentials to this code. Given the manifest/code mismatch, this is more dangerous because it can silently bind a user’s local secret to an unrelated service configuration.

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
90% confidence
Finding
This function is explicitly designed to save an API key into a plaintext .env file, creating long-lived local credential exposure. In a skill whose code appears repurposed from another service, persistent secret storage raises the chance of misrouting or later reuse of credentials by unintended components.

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
90% confidence
Finding
The function’s stated purpose is to set and persist the API key to .env, normalizing insecure long-term storage of a secret. This is dangerous because it encourages users to provide credentials to a skill whose actual configuration appears to target a different backend than advertised.

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
97% confidence
Finding
The dependency is specified with only a lower bound, which allows future installs to resolve to different versions over time. This weakens build reproducibility and can unintentionally introduce breaking changes or newly published vulnerable releases into the skill's environment.

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
97% confidence
Finding
Using an unpinned version for pydantic means the installed package may vary between environments and over time. This can expose the project to supply-chain risk and make security review and incident response harder because the exact dependency state is not fixed.

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
97% confidence
Finding
The pydantic-settings dependency is not pinned to a single version, so installation is nondeterministic. In practice this can allow unreviewed upstream changes or vulnerable versions to enter deployments without code changes in the repository.

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
97% confidence
Finding
An unpinned python-dotenv dependency permits installation of any later version satisfying the minimum, reducing reproducibility and increasing supply-chain exposure. This is especially relevant because environment-loading utilities often handle sensitive configuration data.

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
94% confidence
Finding
The allowed version range includes requests 2.31.0, which has published advisories including credential leakage via malicious URLs and request verification issues in some session flows. In a stock-data service that makes outbound HTTP requests, this dependency context increases relevance because malformed remote URLs or request handling bugs could expose secrets or weaken transport assurances.

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
84% confidence
Finding
The permitted python-dotenv version includes 1.0.1, which is reported as vulnerable to symlink-following file overwrite in set_key. This is only likely to matter if the skill uses python-dotenv to modify .env files or other filesystem paths, so the risk is more contextual and lower from this file alone.

Static analysis

No suspicious patterns detected.