Back to skill

Security audit

火车时刻查询服务

Security checks for vulnerabilities and agentic risk

Overview

This skill presents itself as a Caltrain schedule helper, but it requires a third-party XiaoBenYang API key and stores it locally in plaintext.

Review before installing. Only use this skill if you understand why a XiaoBenYang API key is required for Caltrain data and are comfortable storing that key in a project .env file. Prefer a version that removes the unrelated Gaokao references, clearly scopes the external service, and uses secure or session-only 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 (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/config.py:47
Finding

API Key Persisted in Plaintext Without Restrictive File Permissions

Content
View full analysis

Vulnerability Details

File Location: scripts/config.py, lines 47–66
Vulnerability Type: Plaintext sensitive credential storage
Risk Level: Medium

Vulnerable Code

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()
        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 persists a user-supplied API key in a plaintext .env file. Path.write_text() creates or overwrites the file using permissions derived from the process umask, but the implementation does not explicitly enforce owner-only access. It also does not inspect or correct the permissions of an existing .env file.

Consequently, the credential may be readable by other local users or processes when the runtime environment has a permissive umask, shared project directory, or preexisting .env file with unsafe permissions. The implementation also follows filesystem links without checking whether .env is a symbolic link, which can make the write target dependent on the surrounding filesystem state.

Attack Path

  1. A user provides an API key as required by the Skill instructions.
  2. The agent invokes set_api_key(), which calls save_api_key_to_env().
  3. The function writes the ...[truncated 1015 chars]
Remediation
View remediation

Remediation Suggestions

  1. Prefer session-only credential handling or an operating-system credential manager instead of plaintext project files.
  2. If file persistence is necessary, create the credential file atomically with owner-only mode 0600.
  3. When updating an existing file, verify and correct its permissions before writing.
  4. Refuse to write through symbolic links and validate that the destination is a regular file owned by the expected user.
  5. Store the credential outside shared project directories where practical.
  6. Ensure .env is excluded from version control, build artifacts, backups, diagnostic bundles, and logs.
  7. Document key revocation and rotation procedures in case the file is exposed.
  8. Avoid placing the credential in process-wide environment state unless required, because child processes may inherit it.
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 (32)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill claims to provide Caltrain GTFS queries but appears to manage credentials for an unrelated '小笨羊高考' service, including reading and writing API keys to local configuration. This strongly suggests repurposed or deceptive functionality, increasing the risk of credential harvesting, unauthorized persistence, and off-scope remote access.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill claims to provide Caltrain GTFS queries but appears to manage credentials for an unrelated '小笨羊高考' service, including reading and writing API keys to local configuration. This strongly suggests repurposed or deceptive functionality, increasing the risk of credential harvesting, unauthorized persistence, and off-scope remote access.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

A GTFS-based Caltrain timetable skill should not normally require users to obtain and provide an unrelated third-party API key from an external website, then persist it locally. This creates a strong phishing and credential-capture risk, especially because the credential workflow is central and mandatory despite being unrelated to the declared purpose.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file implements a generic external MCP API client driven by caller-controlled mcp_id, tool_name, and params, which is broader than the advertised Caltrain timetable scope. This creates a capability-expansion risk: if exposed through the skill, users may invoke arbitrary upstream tools or tenants via the configured gateway, potentially causing unauthorized data access or unintended actions outside the stated domain.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file’s behavior does not match the declared Caltrain timetable skill at all: it implements configuration and credential persistence for an unrelated '小笨羊高考' service. This kind of capability mismatch is a strong supply-chain red flag because it can trick reviewers into approving code that handles secrets for a different backend than the advertised skill.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The docstring explicitly labels this as '小笨羊高考Skill配置', directly contradicting the declared train-query skill. That mismatch strongly suggests repurposed or deceptive code, making it more dangerous because reviewers and users may grant trust under false pretenses while the skill interacts with an unrelated external service and its credentials.

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

This code explicitly opens and parses the local .env file to extract XBY_APIKEY for an unrelated service. In the context of a train timetable skill, direct credential harvesting from disk is suspicious and expands secret exposure beyond what the advertised functionality requires.

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

The code conditionally reads the .env file and iterates through its contents to recover a secret, which is unnecessary for the stated train-query purpose. In context, this increases the risk of unauthorized or opaque credential use because the skill is obtaining secrets from local storage for a different backend than advertised.

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

This function is dedicated to saving an API key into a .env file, creating plaintext secret persistence for an unrelated service. In the context of a train schedule skill, this is unjustified secret handling that can lead to credential leakage through local file compromise or accidental repository 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
84% confidence
Finding

The skill exposes capabilities implying environment access, file read/write, and network use, but it does not declare any tool scope or permission boundary. In an agent setting, that omission weakens reviewability and can let a seemingly simple transit skill exercise broader capabilities than users or hosts expect.

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 collect a user API key and save it, but it does not warn that the key will be persisted locally or explain retention and handling. That creates unnecessary secret-exposure risk, particularly because the key appears unrelated to the stated transit functionality and may be stored in a file such as .env.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Using a school-search function example inside a Caltrain timetable skill indicates copy-paste residue and undermines trust in the tool-routing instructions. In context with other mismatches, this increases the chance that the agent could be directed toward unrelated functions or hidden upstream capabilities not apparent from the declared scope.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill can persist an API key into a local .env file and mutate process environment variables even though that behavior is not necessary for a train schedule query tool. Unnecessary secret persistence increases the chance of credential leakage through local file exposure, source-control mistakes, backups, or reuse by unrelated processes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code writes the API key to .env without any user-facing warning or consent flow. Silent credential persistence is dangerous because users may assume the secret is ephemeral, while it actually remains on disk where it can be exposed through file access, backups, or accidental commits.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

Nearly all instructional text and operational requirements are written in Chinese, and the skill does not state that this locale is optional or region-specific. Under the language/locale policy, forcing a specific language without user opt-in can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

Documenting the project as 'xiaobenyang_gaokao_skill' contradicts the declared train-query purpose and suggests the skill was repurposed from an unrelated project. While not directly exploitable on its own, in this context it is a meaningful indicator of deceptive packaging and poor provenance control.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency specification uses a lower-bound constraint instead of an exact pin, which makes builds non-reproducible and can allow unexpected or vulnerable versions to be installed over time. In a service skill that relies on HTTP requests, this increases supply-chain risk because the actual deployed requests version cannot be verified from the manifest alone.

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

requests has multiple known advisories, and because the manifest does not pin an exact version, it is not possible to verify whether the deployed environment is affected. In a train schedule query service that likely performs outbound HTTP requests, a vulnerable requests version could expose credentials or weaken transport/session handling depending on usage.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

Using pydantic>=2.7.0 permits any later major/minor release, which can introduce vulnerable or incompatible versions without review. This is a supply-chain hygiene issue rather than an immediate exploit, but it weakens assurance about what code is actually installed.

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

pydantic has known security advisories, but the open-ended version specifier prevents determining if a vulnerable release may be installed. Given this skill likely parses external or user-provided query inputs, using an unverified parser/validator version can increase denial-of-service or input-processing risk.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The unpinned pydantic-settings dependency allows resolver-selected versions to change across environments and time, making it impossible to confirm whether a deployment includes a vulnerable release. For configuration-loading libraries, this can matter because they often interact with secrets and local files.

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

pydantic-settings has a known advisory and the dependency is not pinned, so the manifest cannot prove the deployment avoids affected versions. Since settings libraries can read secrets and files, ambiguity around the installed version is a meaningful but low-severity supply-chain concern.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

python-dotenv is specified with only a minimum version, so installations may pull different releases with different security properties. Because dotenv tooling commonly reads or writes environment/config files, uncertainty about the exact installed version creates avoidable supply-chain and local file-handling risk.

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