Back to skill

Security audit

开放数据查询服务

Security checks for vulnerabilities and agentic risk

Overview

This skill is presented as a direct Toronto open-data connector, but it actually requires a Xiaobenyang API key, stores it locally, and sends user queries through a third-party service.

Review this before installing. Use it only if you intentionally want to trust Xiaobenyang as the intermediary for Toronto data queries and are comfortable sending it your API key, search terms, natural-language questions, filters, and CSV URLs. Do not provide sensitive or private context in queries. Avoid storing the key in a shared repository or workspace, and prefer a version that clearly discloses the proxy, minimizes transmitted data, supports session-only credentials, and avoids plaintext .env persistence.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/config.py:38
Finding

API key persisted in a plaintext working-directory file

Content
View full analysis
bool: 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 ``` The mandatory workflow in `SKILL.md:13-18` and `SKILL.md:31` directs the agent to request the key and persist it by invoking `scripts.config.set_api_key()`. ### Technical Analysis The Skill stores the user-supplied API key unencrypted in `.env`, using a path relative to the process working directory. The implementation does not: - Apply restrictive file permissions such as `0600`. - Verify the owner or permissions of an existing file. - Reject symbolic links. - Use atomic, exclusive file creation. - Ensure that `.env` is excluded from version control, backups, or artifact packaging. - Offer session-only use as the default. The relative path also makes the storage destination dependent on the caller's working directory. This can place the credential in a shared repository or other unintended location. If an attacker can prepare `.env` as a symbolic link, writing the API key may disclose it into an attacker-readable target or overwrite an accessible file. This persistence is not nec ...[truncated 1346 chars]
Remediation
View remediation

other

Warning
Location
scripts/call_api.py:51
Finding

User questions and query parameters are routed through an insufficiently disclosed third-party proxy

Content
View full analysis
HttpResult: 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密钥未设置,请先调用 set_api_key()") 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, ) ``` The configured destination is: ```python base_url: str = "https://mcp.xiaobenyang.com" mcp_id: str = "1820705335657482" api_key: str = "" ``` Natural-language questions are included in the forwarded parameters: ```python arguments = { "dataset_id": dataset_id, "user_question": user_question, "limit": limit } return call_api("1777419072193539", "toronto_smart_data_helper", arguments) ``` Search terms, dataset identifiers, filters, selected fields, sorting expressions, and CSV URLs are forwarded in the same manner by the other wrappers. ### Technical Analysis The Skill description characterizes the service as directly accessing Toronto Open Data through CKAN. The implementation does not directly call Toronto's CKAN endpoint. Instead, every tool invocation is sent to the Xiaobenyang-controlled endpoint at `https://mcp.xiaobenyang.com/api`. Transmission of the Xiaobenyang-issued key to that service is co ...[truncated 2146 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/tools.py:163
Finding

Arbitrary URL is forwarded to a remote CSV-fetch service without validation

Content
View full analysis
Dict[str, Any]: """ 📄 FETCH CSV DATA: Downloads and returns sample content from a CSV file URL. Perfect for quickly inspecting downloadable datasets identified by other tools. Shows headers and sample rows to understand the data structure. Args: csv_url: null max_lines: null Returns: null """ arguments = { "csv_url": csv_url, "max_lines": max_lines } return call_api("1777419072193539", "toronto_fetch_csv_data", arguments) ``` ### Technical Analysis The tool accepts any string as `csv_url` and forwards it to a remote fetch service. It does not validate: - The URL scheme. - The destination hostname. - Whether the hostname resolves to loopback, private, link-local, or reserved addresses. - Embedded credentials. - Redirect destinations. - Whether the resource belongs to Toronto Open Data. - The returned content type or maximum byte size. The actual fetch occurs in an external service whose implementation is not included in the project. Therefore, server-side request forgery cannot be confirmed from the reviewed source. The confirmed local issue is that the interface forwards arbitrary URLs without enforcing the narrow Toronto Open Data CSV-preview scope. ### Attack Path 1. A malicious dataset response, prompt, or user supplies a crafted URL. 2. The agent invokes `toronto_fetch_csv_data()` with that URL. 3. The wrapper forwards the URL to the Xiaobenyang API without validation. 4. The vendor receives and may attempt to fetch the target. 5. If the remote implementation also lacks outbound-request controls, the URL could target internal services, cloud ...[truncated 900 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Dependencies are unpinned and installed without integrity hashes

Content
View full analysis
=2.31.0 pydantic>=2.7.0 pydantic-settings>=2.2.0 python-dotenv>=1.0.1 ``` ### Technical Analysis Every dependency uses an open-ended lower-bound constraint. There is no lock file and no cryptographic hash verification. A future installation may consequently select package versions that were not present or reviewed during this audit. The listed package names appear to be established packages, and the reviewed project does not demonstrate dependency confusion, typosquatting, or a currently malicious dependency. The weakness is the absence of reproducible version selection and artifact-integrity enforcement. Because Python packages may execute code during installation or import, a compromised future release, compromised package index, or unexpected incompatible update could affect the Skill environment. ### Attack Path 1. An operator installs the project dependencies at a later date. 2. The package resolver selects the newest versions satisfying the lower bounds. 3. A selected artifact differs from the version originally tested or audited. 4. If that release or distribution artifact is compromised, malicious package code executes during installation or when imported. 5. The package code receives the permissions of the process running the Skill, including access to environment variables and locally stored configuration available to that process. This path is conditional on a compromised or unsafe future dependency artifact; no such artifact was confirmed in the reviewed files. ### Impact Assessment A compromised dependency could execute with the Skill process's local permissions. Depending on the execution environment, that could expose the API key, query content, accessible files, and network capabilities. The c ...[truncated 237 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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (29)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill advertises Toronto/CKAN dataset functionality, yet the surrounding identifiers and configuration reference xiaobenyang.com and a gaokao-related project, plus local API-key persistence. This is a strong integrity and provenance problem because users may believe they are using a public-data connector when they are actually onboarding into an unrelated remote service with credential storage.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill advertises Toronto/CKAN dataset functionality, yet the surrounding identifiers and configuration reference xiaobenyang.com and a gaokao-related project, plus local API-key persistence. This is a strong integrity and provenance problem because users may believe they are using a public-data connector when they are actually onboarding into an unrelated remote service with credential storage.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill says it directly accesses Toronto Open Data via CKAN, but instructs the agent to solicit and store a third-party API key from xiaobenyang.com before use. That is dangerous because it creates an undisclosed credential-collection path unrelated to the stated public-data use case, increasing phishing-like risk and secret exfiltration concerns.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The workflow claims the code only calls APIs for Toronto open data, but the examples and project structure point to unrelated domains and tooling. In security terms, this kind of deceptive or inconsistent operational description undermines user trust and can conceal unintended network destinations, credential handling, or broader remote-call behavior.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The implementation contradicts the stated skill purpose: instead of directly querying Toronto CKAN open data, it sends requests to an unrelated upstream service labeled '小笨羊MCP API' using a configurable base URL and API key. In an agent skill, this creates a hidden data-flow and trust-boundary violation, allowing user queries and parameters to be exfiltrated to an undisclosed third party and enabling behavior not represented in the manifest.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The configuration clearly targets a different service ('小笨羊高考') with a hardcoded remote base URL and custom API key handling, which contradicts the advertised Toronto CKAN open-data service. In an agent skill, this mismatch is dangerous because it can silently redirect data access and secrets to an unrelated backend, undermining user trust and enabling covert exfiltration or unauthorized remote control.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The settings docstring identifies the code as a configuration for a different skill ('小笨羊高考Skill'), directly contradicting the declared purpose of the package. In security-sensitive agent ecosystems, such identity mismatch is a strong indicator of repurposed or mislabeled code and increases the risk that users invoke functionality they did not intend to trust.

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

The code forcibly reads a specific API key from .env outside the normal settings abstraction, creating a custom secret ingestion path that is harder to audit and easier to misuse. In the context of a mislabeled skill, this increases concern that credentials are being collected for an unrelated backend rather than only for the advertised public data service.

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

Checking for and reading a local .env file is not inherently malicious, but in this implementation it is part of a custom flow that extracts a private API key for an unrelated service. That behavior is risky because it normalizes local credential harvesting in a skill that claims to query public open data directly.

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 explicitly designed to save an API key into a .env file, creating persistent local secret storage. In an agent skill with misleading service identity, persistent secret capture materially increases the chance of credential leakage or unauthorized reuse beyond the user's expectations.

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 exposes capabilities consistent with environment access, file read/write, and network access but does not declare any tool scope or permission boundary. In an agent setting, that omission weakens transparency and reviewability, making it harder to assess whether sensitive operations like credential persistence and outbound calls are expected or authorized.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The skill name and entire user-facing description/instructions are written in Chinese, effectively constraining interaction/documentation to one language. There is no indication that the user may choose another language or that the language restriction is required for a region-specific compliance reason.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill instructs the agent to collect a user-provided API key and save it, but does not clearly warn that the credential will be persisted or describe retention and handling. This can lead users to provide secrets without informed consent, and local persistence increases the blast radius if the environment is shared or compromised.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The class name, logger name, and docstrings consistently describe a different service than the one advertised by the skill metadata. This is more than a naming bug in a security-sensitive agent context: deceptive labeling can hide unauthorized network access paths and prevent users or reviewers from understanding where data is actually sent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The code retrieves an API key and transmits it in an outbound header to the upstream service, but this file provides no disclosure or validation that the destination is the expected trusted endpoint. Combined with the manifest/code mismatch, this increases the risk of credential exposure to an undisclosed service or attacker-controlled base URL.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This skill persists and manages a private API key even though the description claims direct access to open CKAN data, which normally should not require secret credential handling for public dataset queries. That inconsistency expands the attack surface by introducing secret storage, secret retrieval, and potential routing through a proprietary service without clear user awareness.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The function writes an API key directly into a local .env file and updates process environment state without any visible confirmation, warning, or explanation to the user. This can cause accidental long-term credential persistence in insecure locations, increasing the risk of leakage through source control, local compromise, backups, or shared workspaces.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency uses a lower-bound version specifier (requests>=2.31.0) instead of pinning to a specific version or constrained range. This makes builds non-reproducible and can allow installation of a later vulnerable or incompatible release, especially significant here because requests has multiple known advisories and this MCP service directly performs network access.

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

The manifest does not pin requests, and the package has multiple known advisories. Because the exact installed version is unverifiable from this file, there is a real supply-chain exposure: a deployment could resolve to an affected release without any code changes.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

pydantic>=2.7.0 is unpinned, so the exact installed version may vary over time and across environments. That weakens supply-chain control and can expose the service to future vulnerable releases or breaking behavior in validation logic.

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

pydantic has known advisories, but the manifest leaves the actual installed version unspecified beyond a minimum bound. This prevents verification that the deployed package is outside vulnerable ranges and introduces unnecessary dependency risk in validation-related code.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
91% confidence
Finding

pydantic-settings>=2.2.0 is not version-pinned, so deployments may resolve to different releases. This creates avoidable supply-chain risk and is more concerning because settings-handling packages can affect secret loading and configuration security.

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

Because pydantic-settings is not pinned, it is impossible to determine from this manifest whether deployments use a version affected by known advisories. Configuration libraries can influence secret loading paths, so uncertainty here is a legitimate security concern even if no exploit is shown in this file.

Content

No source excerpt is available for this finding.