Back to skill

Security audit

柏林公共服务查询服务

Security checks for vulnerabilities and agentic risk

Overview

This skill needs review because a Berlin-services lookup skill asks for and stores a Xiaobenyang API key in plaintext and sends it to a configurable third-party endpoint.

Install only after confirming that Xiaobenyang is the intended and trusted provider for the Berlin service data. Do not provide a valuable or reused API key unless plaintext .env storage is acceptable in your environment, and prefer a version that removes local secret write-back, pins dependencies, and locks the credential-bearing endpoint to the intended host.

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/call_api.py:48
Finding

API credential disclosure through a configurable upstream endpoint

Content
View full analysis
HttpResult: """调用小笨羊MCP工具""" 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", } # data = {k: str(v) if v is not None else "" for k, v in params.items()} t0 = time.time() try: resp = self._session.post( url=url, headers=headers, data=json.dumps(params), timeout=settings.timeout_seconds, ) ``` ### Technical Analysis The upstream `base_url` is a security-sensitive setting because every API request sends the user's `XBY-APIKEY` credential to that destination. Pydantic Settings permits this value to be overridden through the `XBY_GAOKAO_BASE_URL` environment variable or the working-directory `.env` file. The request logic constructs a URL directly from this configurable value and attaches the API key without validating the URL scheme, hostname, port, or origin. Consequently, an attacker who can influence the process environment or place a crafted `.env` file in the working directory can redirect authenticated requests to an attacker-controlled server. TLS does not prevent this attack if the subst ...[truncated 1742 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
  • 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
96% confidence
Finding

This finding indicates the skill manages and persists an API key for an unrelated service and targets mcp.xiaobenyang.com rather than an obvious Berlin-government data source. That creates a trust-boundary violation: sensitive user credentials are being collected and stored for a remote service whose role is inconsistent with the advertised function.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

This finding indicates the skill manages and persists an API key for an unrelated service and targets mcp.xiaobenyang.com rather than an obvious Berlin-government data source. That creates a trust-boundary violation: sensitive user credentials are being collected and stored for a remote service whose role is inconsistent with the advertised function.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill's documentation claims a Berlin services workflow, but the API-key acquisition flow and metadata reference Xiaobenyang/gaokao-related infrastructure. Such semantic inconsistency is a strong indicator of repurposed or misleading skill content, which can trick users into supplying credentials under false pretenses.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The example invocation shows a school-search function with gaokao-style parameters even though the skill is presented as a Berlin public-services query service. That contradiction suggests the routing guidance may direct the model toward unintended or broader capabilities, undermining least surprise and enabling misuse of the skill as a generic proxy.

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

The post-init hook forcibly reads .env and extracts XBY_APIKEY manually, bypassing normal typed configuration flow and explicitly targeting a credential. In a skill context, custom secret scraping from local files is unnecessary and increases the chance of unintended credential ingestion from the workspace.

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

Creating a direct Path('.env') reference for credential retrieval contributes to explicit local secret access behavior. In an otherwise public-service query skill, this local file access is suspicious because it seeks secrets from the workspace rather than using approved runtime secret sources.

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

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The module includes functionality to persist an API key into a local .env file and expose helper functions to set and retrieve it, which is unrelated to a public Berlin services lookup skill. Persisting secrets to project-local plaintext storage increases the chance of accidental disclosure through source control, logs, backups, or later file reads by other components.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code implements local credential write-back for XBY_APIKEY despite the advertised skill being a public information retrieval service. This expands the attack surface by allowing sensitive credentials to be stored on disk without necessity, making compromise easier if the workspace is accessible to users, other skills, or packaging processes.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The function explicitly saves an API key to .env, creating plaintext credential storage on disk. This is dangerous because .env files are commonly copied, committed, or exposed through debugging and packaging, and the behavior is especially unjustified for a public administrative lookup skill.

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

The skill exposes capabilities consistent with environment access, local file read/write, and network access, yet the manifest provides no explicit tool scope or permissions boundary. In a skill that also asks the model to collect and persist API keys, this lack of declared scope increases the chance of overbroad execution and hidden side effects.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The skill name, description, workflow, and operational instructions are written entirely in Chinese, with no indication that users may choose another language or that Chinese is a required locale. For a Berlin public-services lookup skill, this reads as a language constraint imposed by the skill rather than a documented, justified regional compliance requirement.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill explicitly instructs the model to solicit an API key from the user during normal conversation and persist it locally. Collecting secrets through general chat flow and writing them to a local .env file increases the risk of accidental disclosure, insecure storage, exfiltration by other components, and user confusion about who is receiving the credential.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

A project structure labeled xiaobenyang_gaokao_skill conflicts with the stated Berlin public-services purpose. While naming alone is not proof of exploitability, in this context it reinforces the evidence that the package may be repackaged from unrelated code and could mislead reviewers about provenance and actual behavior.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

清单描述该技能用于搜索和检索柏林当局提供的公共服务信息,但此文件只实现了一个面向任意 mcp_id、tool_name 和 params 的通用上游 API 调用器,没有任何与柏林行政服务数据、查询范围限制或特定资源端点相关的约束。这样的实现语义上更像一个泛化的远程工具代理,而非专用的柏林公共服务查询能力。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code accesses a sensitive credential via get_api_key() and sends it in the XBY-APIKEY request header during a network call. While the module has internal comments/docstrings and logging, none of them clearly disclose to the user that a secret will be used and transmitted to an external service.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The comments and naming indicate this file belongs to a different '小笨羊高考' skill and uses unrelated XBY_GAOKAO/XBY_APIKEY identifiers, which is inconsistent with the declared Berlin public service purpose. Such provenance mismatch is a supply-chain red flag because repurposed code can conceal undeclared network dependencies, inappropriate secret handling, or functionality not reviewed for this skill's threat model.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The API key is silently persisted to .env with no user warning, consent, or indication that a plaintext secret is being written to disk. Even if intended for convenience, this can surprise operators and cause long-lived credential exposure in developer environments, containers, snapshots, or repositories.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency list uses a lower-bound specifier (requests>=2.31.0) rather than an exact pinned version, which makes builds non-reproducible and can pull in unexpected releases over time. In a server-side skill, this increases supply-chain uncertainty and complicates verification against known vulnerable or breaking versions.

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

The manifest does not pin requests, and the package has multiple published advisories, so it is impossible to verify from this file whether deployments will use an affected version. In a network-facing service, an unresolved requests version is more concerning because HTTP client behavior can directly affect credential handling, TLS verification, and request security.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

pydantic>=2.7.0 is unpinned, so installations may resolve to different versions depending on when and where the skill is deployed. This weakens reproducibility and can introduce vulnerable or incompatible releases without code changes.

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

Because pydantic is not pinned, the effective installed version cannot be matched reliably against known advisories. For a service likely to parse external input, uncertainty around a validation library can expose the deployment to denial-of-service or parsing flaws present in some releases.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

pydantic-settings>=2.2.0 allows any newer version, which creates uncertainty about the actual installed package and its security posture. For infrastructure-facing code that may load secrets or environment configuration, this increases supply-chain risk even if no exploit is visible in this file alone.

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

pydantic-settings has known advisories, and the absence of an exact version means the deployed build may resolve to a vulnerable release without visibility in the manifest. This is relevant in a service context because settings libraries may process secrets paths and filesystem-backed configuration.

Content

No source excerpt is available for this finding.