Back to skill

Security audit

地理空间数据访问服务

Security checks for vulnerabilities and agentic risk

Overview

The skill claims to access geospatial data, but it stores an API key locally and proxies all tool calls through a third-party Xiaobenyang API with inconsistent reused documentation.

Install only if you are comfortable giving a Xiaobenyang API key to this skill and having it stored in a local .env file. Treat the package as a third-party API proxy for Source Cooperative-style queries, not as a direct local geospatial client; review the stale gaokao/school references and consider using an environment variable or secret manager instead of persistent .env storage.

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

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill advertises no declared permissions while its documented behavior requires environment access, local file read/write, and network calls. This undermines least-privilege review and prevents users or the platform from making an informed trust decision, especially because it also stores credentials locally and sends them to a remote service.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The documented purpose says this is a geospatial MCP/JSON-RPC service, but the behavior described by analysis involves saving an API key locally and proxying requests to a fixed remote API with custom headers. This mismatch is dangerous because it can mislead users into granting secrets and permissions under false pretenses, reducing scrutiny of credential handling and outbound data flow.

Description-Behavior Mismatch

High
Confidence
96% confidence
Finding
The documentation/workflow describes a different gaokao or school-search credentialed API flow than the claimed geospatial dataset service. Such identity confusion is a strong trust and phishing risk because users may provide API keys and approve actions for a skill whose actual purpose is unclear or misrepresented.

Intent-Code Divergence

High
Confidence
95% confidence
Finding
The inline example tells the model to call a non-existent search_schools function, contradicting the listed geospatial toolset. This increases the chance of unsafe fallback behavior, tool-routing errors, or hidden dependency on an unreviewed backend flow, all of which weaken assurance about what actions the skill will actually perform.

Intent-Code Divergence

Medium
Confidence
90% confidence
Finding
The project structure and API-key setup text conflict with the Source Cooperative geospatial tool descriptions, indicating the skill may be stitched together from unrelated components. This inconsistency makes it hard to verify actual data flows and increases the risk of undisclosed credential storage or calls to unintended services.

Description-Behavior Mismatch

Medium
Confidence
87% confidence
Finding
The code adds credential persistence logic that writes an API key into a local .env file, which exceeds simple runtime configuration and creates a secret-at-rest risk. In the context of a geospatial data access skill, storing credentials locally is not inherently required and increases exposure if the workspace, logs, backups, or repository contents are later accessed by another process or user.

Context-Inappropriate Capability

Medium
Confidence
83% confidence
Finding
This function implements local credential storage capability by reading and rewriting .env contents with the supplied API key. Even if intended for convenience, local secret storage creates avoidable credential exposure risk and is not clearly justified by the declared geospatial discovery/access purpose of the skill.

Intent-Code Divergence

High
Confidence
94% confidence
Finding
The class docstring references an unrelated '小笨羊高考Skill配置' while the package is presented as a geospatial data access service, indicating code reuse or repurposing without proper review. Such mismatches are a strong supply-chain red flag because they can conceal inherited behaviors, undocumented data flows, or capabilities unrelated to the declared skill function.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The skill instructs the model to ask the user for an API key and save it via local configuration, but it does not clearly warn that the credential will be persisted. Users may disclose a secret without understanding retention, scope of use, or whether it will later be transmitted to a remote service.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The API key is written to .env automatically with no user-facing warning, confirmation, or explanation that a secret will be persisted on disk. This can lead to accidental long-term storage of credentials in locations that may be backed up, shared, or committed to source control.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The search function explicitly advertises discovery of unpublished products across all accounts, which can expose non-public dataset existence and metadata to any client invoking the skill. Even if the underlying storage permits enumeration, surfacing unpublished resources without warning, authorization checks, or scope restriction creates an information disclosure risk and may reveal sensitive or embargoed assets.

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
The code force-reads .env manually in model_post_init to extract XBY_APIKEY, bypassing normal configuration expectations and creating an undisclosed credential access path. This makes secret handling less transparent and harder to audit, especially given the mismatch between the declared skill purpose and the reused configuration naming.

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
82% confidence
Finding
Opening and reading the entire .env file to locate a specific API key increases the scope of credential access beyond what is needed and may expose other secrets during debugging, logging, or future code changes. In a skill of this type, broad local secret file access is more suspicious because it is not obviously essential to geospatial querying itself.

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 explicitly implements saving an API key to a local .env file, creating a persistent secret store in the project directory. That increases the chance of credential disclosure through local compromise, backups, shared workspaces, or accidental repository inclusion.

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
88% confidence
Finding
The public helper advertises persistent credential storage as normal behavior ('设置API key并持久化到.env'), which encourages insecure handling of secrets by design. Packaging this into the skill makes insecure storage the default operational path rather than an exceptional, controlled action.

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 a lower-bound constraint (`requests>=2.31.0`) rather than an exact pin or bounded range, which makes builds non-reproducible and can pull in unexpected future releases. In a network-facing MCP service, dependency drift increases supply-chain risk and can silently introduce breaking changes or newly published malicious/compromised versions.

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
`pydantic>=2.7.0` is unpinned, so installations may resolve to different versions over time. That creates reproducibility and supply-chain integrity issues, especially for a service that parses structured client input and may be exposed to untrusted JSON-RPC requests.

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
96% confidence
Finding
`pydantic-settings>=2.2.0` is not fixed to a specific version, allowing uncontrolled dependency resolution. While not an exploit by itself, this weakens build determinism and can introduce vulnerable or incompatible transitive packages into the deployment.

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
`python-dotenv>=1.0.1` is unpinned, so future installations may consume an unintended release. For server-side software that may load environment configuration and secrets, uncontrolled dependency updates increase operational and supply-chain risk.

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
93% confidence
Finding
The requirements allow `requests` version 2.31.0 or later, and the finding correctly notes that 2.31.0 has published advisories. Because the package is specified as `>=2.31.0` rather than exactly `==2.31.0`, this is conditionally vulnerable: deployments may still resolve to the affected version, and this service is likely to make outbound HTTP requests to discover or access remote geospatial data, which increases relevance of request-handling flaws such as credential leakage or verification issues.

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 requirement permits `python-dotenv` 1.0.1, which the advisory flags for unsafe symlink handling in `set_key`. This is a conditional vulnerability because the file only declares `>=1.0.1`, but if the deployed environment resolves to that version and the skill uses dotenv write operations on attacker-influenced paths, it could enable arbitrary file overwrite; the risk is somewhat contextual because many services only read `.env` files.

Static analysis

No suspicious patterns detected.