Back to skill

Security audit

警察数据查询服务

Security checks for vulnerabilities and agentic risk

Overview

This skill appears to provide UK police-data lookups, but it routes through an unrelated XiaoBenYang service, asks for and stores an API key locally, and contains mismatched Gaokao project remnants.

Review before installing. Only use this skill if you intentionally want to send police-data queries and an XiaoBenYang API key to the XiaoBenYang MCP backend, and avoid entering valuable or reusable credentials unless the publisher explains the service relationship and replaces plaintext .env storage with safer secret handling.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/config.py:43
Finding

API Key Persisted in an Unprotected Plaintext File

Content
View full analysis

Vulnerability Details

File Location: scripts/config.py:43-61
Vulnerability Type: Plaintext credential storage with insufficient file protection
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

Technical Analysis

The function writes the user-supplied API key in plaintext to a predictable .env file in the process's current working directory. Path.write_text() does not explicitly enforce restrictive permissions such as 0600; effective permissions depend on the operating system and process umask.

The code also does not verify that .env is a regular file owned by the current user. If an attacker can control the working directory or pre-create .env as a symbolic link, the write may follow that link. The read-modify-write operation is not atomic, creating an additional opportunity for race conditions.

The credential is also copied into the process environment, where it may be exposed to same-user diagnostic tools, crash reporting, or child processes.

Attack Path

  1. A user supplies a valid API key as required by the Skill workflow.
  2. The Agent calls set_api_key(), which invokes save_api_key_to_env().
  3. The API key is written as `XBY_APIKEY=<secret&gt ...[truncated 1223 chars]
Remediation
View remediation

Remediation Suggestions

  1. Prefer a platform credential manager, operating-system keyring, or session-only secret injection instead of plaintext file persistence.
  2. If file storage is required, use a fixed per-user configuration directory rather than the current working directory.
  3. Create the credential file with restrictive 0600 permissions and verify permissions after every replacement.
  4. Reject symbolic links and verify that the destination is a regular file owned by the current user.
  5. Write to a securely created temporary file in the same directory, set its permissions, flush it, and atomically replace the destination.
  6. Add .env to .gitignore and provide automated secret scanning in continuous integration.
  7. Avoid copying the key into the process environment unless required. Never pass it to child processes.
  8. Document the storage location and obtain explicit user consent before persisting the credential.

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Dependencies Are Not Pinned to Audited Versions

Content
View full analysis

Vulnerability Details

File Location: requirements.txt:1-4
Vulnerability Type: Unbounded dependency resolution and non-reproducible builds
Risk Level: Low

Vulnerable Code

text
requests&gt;=2.31.0
pydantic&gt;=2.7.0
pydantic-settings&gt;=2.2.0
python-dotenv&gt;=1.0.1

Technical Analysis

Each dependency specifies only a minimum version and permits the package manager to install any later release. Consequently, a future installation may execute dependency code that was not present during this audit.

The listed package names correspond to established packages; there is no evidence of typosquatting, dependency confusion, or a currently malicious package in the project. The weakness is the absence of exact version and integrity constraints, which makes builds non-reproducible and expands exposure to future compromised, vulnerable, or incompatible releases.

No lock file or package hashes are included to verify that downloaded artifacts match reviewed versions.

Attack Path

  1. A user or deployment system installs the project dependencies at a later date.
  2. The package resolver selects newer versions permitted by the &gt;= constraints.
  3. A selected release contains a vulnerability, malicious modification, compromised maintainer release, or unexpected breaking behavior.
  4. The unreviewed package code executes during installation or when the Skill imports and uses the dependency.
  5. The resulting impact is determined by the permissions of the installation or Skill process.

This path is conditional on an unsafe or compromised future dependency release; the audited files do not demonstrate that any currently named dependency is malicious.

Impact Assessment

Dependency code normally executes with the same operating-system privileges as the installer or Skill process. A compromised package could therefore read accessible files and credentials, alter application behavior, or make ne ...[truncated 266 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin every direct and transitive dependency to reviewed versions using a lock file.
  2. Generate and enforce cryptographic hashes, such as with pip-compile --generate-hashes followed by pip install --require-hashes.
  3. Retrieve packages only from an explicitly trusted package index.
  4. Run automated dependency vulnerability scanning and update packages through a controlled review process.
  5. Test dependency updates in an isolated environment before deployment.
  6. Rebuild lock files periodically so security patches are adopted deliberately rather than through unrestricted resolution.
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 (29)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill claims to query UK police data, but the docs point to a Gaokao-related project structure and instruct reading/writing a local .env with XBY_APIKEY and XBY_GAOKAO-style configuration. That inconsistency strongly suggests either repurposed code or deceptive packaging, creating risk of credential capture, unauthorized persistence of secrets, and use of unrelated external resources.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill claims to query UK police data, but the docs point to a Gaokao-related project structure and instruct reading/writing a local .env with XBY_APIKEY and XBY_GAOKAO-style configuration. That inconsistency strongly suggests either repurposed code or deceptive packaging, creating risk of credential capture, unauthorized persistence of secrets, and use of unrelated external resources.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The call_tool method accepts arbitrary tool_name and mcp_id values and forwards them directly as headers to the upstream API, effectively exposing a general-purpose remote tool invocation primitive. If untrusted input can reach this function, an attacker could invoke unintended upstream capabilities under this service's API key, making the mismatch with the declared police-data-only purpose especially dangerous.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The class docstring identifies the code as a Gaokao skill, directly contradicting the manifest that claims this is a UK police-data query service. Identity mismatches like this are a strong signal of repurposed or swapped code and make it harder to trust where data and credentials are actually being sent.

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 mismatched to the declared police-data skill: it uses XBY_GAOKAO-prefixed settings, an xiaobenyang.com endpoint, and an unrelated XBY_APIKEY secret. This indicates either code reuse from a different product or hidden cross-service integration, which can misroute sensitive requests and secrets to an unintended backend.

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
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 32)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 XBY_APIKEY from a local .env file regardless of the declared police-data skill identity, pulling in credentials for an apparently unrelated service. In context, this is dangerous because it can silently bind this skill to another backend and consume secrets the user did not intend to expose to this component.

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

Overriding configuration with XBY_APIKEY from the process environment wires this skill to consume secrets for a different service than advertised. In the context of a police-data skill, silently importing unrelated credentials increases the chance of unauthorized cross-service access or data routing to an unintended endpoint.

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 persist API keys into .env, creating a durable local credential store. If the repository, working directory, or backups are exposed, the key can be recovered and reused; this is more concerning here because the key appears unrelated to the declared police-data capability.

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

The skill declares no explicit tool scope or permission boundaries even though its documented behavior includes credential access, local file writes, and network/API usage. In an agent setting, missing scope declarations make it harder to constrain what the skill may do and increase the chance of over-privileged execution or unsafe operator assumptions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill name, description, workflow instructions, and operational requirements are written in Chinese, while the service itself is for querying UK police data. There is no statement offering a language choice or explaining that Chinese is a required locale, which can constitute a language/locale policy violation under the natural-language policy rules.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The authentication instructions direct users to obtain an API key from an unrelated third-party domain despite the skill presenting itself as a UK police data service. This is a strong trust-boundary violation: users can be tricked into providing credentials for an unexpected service, and the mismatch makes phishing or data redirection more plausible.

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 ask the user for an API key and persist it via configuration, but it does not warn the user that their credential will be written to local storage. This undermines informed consent for secret handling and increases the risk of credential exposure through filesystem access, backups, logs, or later reuse by other components.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The workflow example includes an unrelated search_schools call, indicating copied or mixed instructions from another skill. In security terms, this kind of cross-domain mismatch is dangerous because it suggests the agent may be routed to unintended functions or external services that users did not authorize under the stated police-data use case.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This client is implemented as a generic MCP API invoker driven by caller-controlled mcp_id, tool_name, and params, rather than being constrained to the advertised police-data use case. In the context of a skill presented as a police data query service, this broad capability increases the chance of unauthorized access to unrelated remote tools or unintended data flows if higher layers expose these parameters to users.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The class and function docstrings and the raised error/message strings are written only in Chinese, with no indication that the skill is region-specific or that users can choose another language. This creates a natural-language locale policy issue because the skill implicitly enforces a specific language for user-facing communication.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This module persists API keys into a local .env file even though the skill description does not imply local secret storage is necessary. Persisting credentials expands exposure through accidental source control commits, local file disclosure, backups, or other processes reading the working directory.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The code silently writes the provided API key to .env without any user-facing warning or consent flow. Users may believe they are supplying a transient secret, when in fact it is being persisted on disk where it may be retained and exposed beyond the current session.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The project structure names the package as a Gaokao skill while the skill is advertised as a police-data service. While this alone may not prove exploitation, it is a substantive integrity signal that the package may be mislabeled or assembled from unrelated components, reducing trust and increasing the chance of hidden behavior.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% 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 allow introduction of vulnerable or incompatible releases without any code change in the project.

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

requests has multiple known advisories, and because the manifest does not pin an exact version, it is impossible to verify from this file alone whether deployed environments are using a fixed or affected release. In a network-facing police-data query service, uncertainty around HTTP client security is meaningful because the package handles outbound requests and possibly credentials, redirects, or proxy behavior.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

Using pydantic>=2.7.0 permits any newer release to be installed, which makes the runtime environment non-deterministic. If a future or transitive-compatible release contains a security regression, affected deployments could silently pick it up.

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

pydantic has known advisories, but the open-ended version specifier prevents verification that installations are on a patched release. Since this service likely parses external API responses and user-supplied parameters, uncertainty in a core validation library increases risk of denial-of-service or parsing-related weaknesses if an affected version is resolved.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

An unpinned pydantic-settings dependency allows different environments to install different versions, reducing supply-chain control and repeatability. This makes it harder to prove whether a deployed instance is affected by known advisories and increases exposure to accidental insecure upgrades.

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