Back to skill

Security audit

Xiaozhi Mcp Openclaw Official

Security checks for vulnerabilities and agentic risk

Overview

This skill is a real XiaoZhi-to-LLM bridge, but it can expose API keys, user queries, and MCP tokens through under-disclosed network defaults and logging.

Review before installing. Only use this if you trust both the XiaoZhi MCP endpoint and the LLM backend. Explicitly set OPENAI_BASE to the intended HTTPS backend, use a narrowly scoped and rotated OPENAI_KEY, avoid putting reusable tokens in URLs where logs may capture them, and consider pinning dependencies before deployment.

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

other

Error
Location
openclaw_mcp.py:10
Finding

Undisclosed Third-Party Backend Can Receive API Credentials and User Queries

Content
View full analysis

Vulnerability Details

File Location: openclaw_mcp.py, lines 10 and 27-39
Vulnerability Type: Credential and user-data disclosure to an undisclosed third party
Risk Level: High

Vulnerable Code

python
OPENAI_BASE = os.environ.get('OPENAI_BASE', 'https://openclaw.994938.xyz/v1')
python
headers = {
    'Authorization': f'Bearer {OPENAI_KEY}',
    'Content-Type': 'application/json'
}
payload = {
    'model': MODEL,
    'messages': [
        {'role': 'system', 'content': SYSTEM_PROMPT},
        {'role': 'user', 'content': message}
    ],
    'max_tokens': 512,
    'temperature': 0.7
}

try:
    r = requests.post(f'{OPENAI_BASE}/chat/completions', headers=headers, json=payload, timeout=TIMEOUT)

Technical Analysis

The backend URL defaults to https://openclaw.994938.xyz/v1 when OPENAI_BASE is absent. Requests to this backend contain both the OPENAI_KEY value in the Authorization header and the complete user query in the JSON body.

The documentation tells users to configure OPENAI_BASE, but it does not identify this fallback domain or explain that credentials and conversation content can be transmitted to it. Consequently, an omitted, misspelled, or unavailable environment variable silently redirects sensitive data to the hardcoded host instead of failing securely.

Because TLS only protects data while it is in transit, it does not prevent the receiving server from reading, retaining, or misusing the bearer credential and submitted messages.

Attack Path

  1. A user installs and starts the bridge.
  2. The user supplies OPENAI_KEY but omits or misspells OPENAI_BASE.
  3. The application silently selects https://openclaw.994938.xyz/v1.
  4. A remote MCP client invokes openclaw_query with user-controlled or sensitive text.
  5. The application sends the API key in the bearer header and the complete query in the request body to the hardcoded server.

...[truncated 822 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove the hardcoded third-party fallback and require explicit configuration:
    python
    OPENAI_BASE = os.environ.get('OPENAI_BASE')
    if not OPENAI_BASE:
        raise RuntimeError('OPENAI_BASE must be explicitly configured')
    
  • Validate the destination before sending credentials. Require HTTPS and restrict the hostname to an administrator-controlled allowlist.
  • Reject URLs containing embedded credentials, unexpected ports, fragments, or non-HTTPS schemes.
  • Clearly disclose every service that receives user content and credentials.
  • Use a narrowly scoped API key with usage limits and regular rotation.
  • Revoke and replace any key that may already have been transmitted to the fallback domain.
  • Consider adding an explicit startup confirmation that displays the sanitized destination hostname before enabling tool calls.

T09 · Insecure Skill Coding Practices

Error
Location
mcp_pipe.py:49
Finding

MCP Bearer Token Is Written to Application Logs

Content
View full analysis

Vulnerability Details

File Location: mcp_pipe.py, lines 4-5 and 49-50
Vulnerability Type: Plaintext sensitive information in logs
Risk Level: High

Vulnerable Code

python
Usage:
  export MCP_ENDPOINT=wss://api.xiaozhi.me/mcp/?token=...
python
async def connect_once(uri, script_path):
    logger.info(f'Connecting to {uri}')

Technical Analysis

The documented MCP endpoint carries its authentication token in the URL query string. connect_once logs the complete URI without redacting query parameters. As a result, the bearer token is exposed whenever a connection attempt is made.

Logs commonly persist in terminal scrollback, redirected files, container logs, CI output, process supervisors, system journals, monitoring platforms, and support bundles. Access controls and retention policies for those systems are often broader than those applied to authentication secrets.

Connection retries can also cause the same token to be recorded repeatedly, increasing its exposure across log collectors and backups.

Attack Path

  1. The operator configures MCP_ENDPOINT using the documented token-bearing URL.
  2. The bridge starts or reconnects to the endpoint.
  3. connect_once writes the complete URL, including the token query parameter, at the information log level.
  4. The log is retained by a terminal, service manager, container platform, CI system, or centralized logging service.
  5. A local user, support operator, log-reader account, or compromised monitoring system retrieves the token.
  6. The attacker uses the token-bearing endpoint URL to impersonate the legitimate bridge or access the associated MCP connection, subject to the endpoint's server-side controls.

Impact Assessment

Any principal with access to application logs may obtain the MCP bearer token without access to the original environment configuration. If the token is reusable, the attacker may authenticate to th ...[truncated 368 chars]

Remediation
View remediation

Remediation Suggestions

  • Never log the complete authentication URL.
  • Parse the URI and log only non-sensitive components such as scheme and hostname:
    python
    from urllib.parse import urlsplit
    
    parsed = urlsplit(uri)
    logger.info('Connecting to %s://%s', parsed.scheme, parsed.hostname)
    
  • If a path must be logged, explicitly discard the query string and fragment.
  • Add a reusable redaction filter for sensitive parameter names such as token, key, secret, and authorization.
  • Prefer authentication headers or another credential mechanism outside the URL if supported by the service.
  • Review existing terminal records, service journals, CI logs, and centralized logging systems for exposed URLs.
  • Revoke and rotate any token that may already have been logged.
  • Add automated tests verifying that known secret values never appear in generated log records.

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Open-Ended Dependency Constraints Permit Unreviewed Package Resolution

Content
View full analysis

Vulnerability Details

File Location: requirements.txt, lines 1-4
Vulnerability Type: Unpinned third-party dependencies and non-reproducible installation
Risk Level: Medium

Vulnerable Code

text
fastmcp>=0.1.0
requests>=2.31.0
websockets>=12.0
python-dotenv>=1.0.0

The documented installation command is:

bash
pip install -r requirements.txt

Technical Analysis

Every dependency uses an open-ended minimum-version constraint. A future installation can therefore select any later release available from the configured package index, including releases that were not present or reviewed when this project was audited.

This prevents reproducible builds and leaves the project exposed to upstream account compromise, malicious future releases, dependency-resolution changes, and unexpected breaking behavior. Python package installation can execute build-system or installation-related code, while imported packages execute code at application runtime.

The audit did not establish that any currently named package is malicious. The confirmed weakness is that the dependency policy does not constrain installations to reviewed artifacts.

Attack Path

  1. A user follows the documented pip install -r requirements.txt instruction.
  2. pip queries the configured package index and resolves the newest versions satisfying the lower bounds.
  3. A package maintainer account, package index, mirror, or dependency release is compromised, or a future release introduces malicious behavior.
  4. The malicious or compromised version still satisfies the open-ended constraint.
  5. pip downloads and installs that artifact.
  6. Malicious code executes during package building, installation, import, or normal application runtime with the privileges of the user running the bridge.

Impact Assessment

A compromised dependency could execute arbitrary Python code under the installing or applica ...[truncated 478 chars]

Remediation
View remediation

Remediation Suggestions

  • Pin each direct and transitive dependency to a reviewed exact version.
  • Generate and commit a lock or constraints file using a controlled build process.
  • Require package hashes during installation, for example with pip install --require-hashes.
  • Download packages only from a trusted, explicitly configured package index or internal mirror.
  • Review dependency changes before updating the lock file.
  • Run vulnerability and provenance checks in continuous integration.
  • Build and install dependencies in an isolated, least-privileged environment.
  • Establish a controlled update process so security patches can be adopted after testing 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
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (25)

Tainted flow: 'headers' from os.environ.get (line 25, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · openclaw_mcp.py (reported line 40)May include surrounding context.

python
}

    try:
        r = requests.post(f'{OPENAI_BASE}/chat/completions', headers=headers, json=payload, timeout=TIMEOUT)
        r.raise_for_status()
        data = r.json()
        reply = data['choices'][0]['message']['content']

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 · README.md (reported line 32)May include surrounding context.

text
2. 配置环境变量:
```bash
cp .env.example .env
nano .env
  1. 启动:

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 · README.md (reported line 82)May include surrounding context.

text
2. 配置环境变量:
```bash
cp .env.example .env
nano .env
  1. 启动:

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 · README.md (reported line 33)May include surrounding context.

  1. 配置环境变量:
bash
cp .env.example .env
nano .env
  1. 启动:
bash

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 · README.md (reported line 83)May include surrounding context.

  1. 配置环境变量:
bash
cp .env.example .env
nano .env
  1. 启动:
bash

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 · SKILL.md (reported line 40)May include surrounding context.

  1. 配置环境变量:
bash
cp .env.example .env
nano .env
  1. 启动:
bash

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 · SKILL.md (reported line 92)May include surrounding context.

  1. 配置环境变量:
bash
cp .env.example .env
nano .env
  1. 启动:
bash

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
81% confidence
Finding

The skill documents capabilities that rely on environment variables, network access, and shell execution, but it does not declare any explicit tool scope or permission boundaries. In an agent ecosystem, this increases the chance of overbroad execution or unintended access because operators and policy engines cannot easily constrain what the skill is allowed to do.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The trigger condition 'when the user mentions specific keywords or needs external capability' is overly broad and underspecified, which can cause unnecessary or unintended tool invocation. That expands data exposure to external services and may let routine conversation be forwarded to a networked backend without clear user intent or policy checks.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The English tool-use guidance is similarly vague, allowing invocation whenever 'an external capability is needed' without concrete limits. In a bridge that forwards prompts to external systems, ambiguity increases the risk of unintended network use, privacy leakage, and policy bypass through broad interpretation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code transparently forwards all stdin/stdout traffic between a local MCP process and a remote WebSocket endpoint, creating a bidirectional data exfiltration and command channel. In the skill context, that is especially sensitive because MCP tools may expose prompts, tool outputs, local context, or secrets to the remote endpoint without any runtime consent prompt, filtering, authentication hardening, or policy checks beyond possession of the endpoint URL/token.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · mcp_pipe.py (reported line 53)May include surrounding context.

python
async def connect_once(uri, script_path):
    logger.info(f'Connecting to {uri}')
    async with websockets.connect(uri) as websocket:
        process = subprocess.Popen(
            ['python3', script_path],
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The default system prompt instructs the backend to always return concise Chinese output for voice playback. This is a natural-language policy concern because it imposes a specific language on all users without offering language selection or documenting a justified locale restriction.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
84% confidence
Finding

This code explicitly transmits user-supplied content to an external network endpoint, which is an inherent data-exposure risk for an MCP tool bridging a device assistant to a remote LLM backend. The skill context makes this more sensitive because it is designed to be invoked for complex queries and external assistance, increasing the chance that sensitive user content, prompt context, or proprietary instructions are sent off-box.

Content

Scanner excerpt · openclaw_mcp.py (reported line 40)May include surrounding context.

python
}

    try:
        r = requests.post(f'{OPENAI_BASE}/chat/completions', headers=headers, json=payload, timeout=TIMEOUT)
        r.raise_for_status()
        data = r.json()
        reply = data['choices'][0]['message']['content']

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The tool forwards the full user message and system prompt to an external service without any in-tool disclosure, consent check, or data-minimization step. In an MCP bridge used by a voice/assistant device, users may reasonably assume local processing, so silent transmission can expose sensitive speech, personal data, or operational context to a third-party backend.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The skill reads an API key from the environment and uses it for outbound requests, but there is no comment, docstring warning, or user-facing documentation in this file explaining that external credentials are required and will be used. This is a safety-relevant behavior because it involves sensitive configuration and third-party service access.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

The dependency is specified with a lower bound only, which allows future installs to resolve to different versions over time. This weakens reproducibility and can unintentionally introduce vulnerable or incompatible releases into the deployment pipeline.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
fastmcp>=0.1.0
requests>=2.31.0
websockets>=12.0
python-dotenv>=1.0.0

Unverifiable Dependency: fastmcp has 14 known advisory(ies) (CVE-2025-69196 (FastMCP OAuth Proxy token reuse across MCP servers); GHSA-c2jp-c369-7pvx (FastMCP Auth Integration Allows for Confused Deputy Account Takeover); CVE-2025-64340 (FastMCP has a Command Injection vulnerability - Gemini CLI) +11 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
94% confidence
Finding

The manifest does not pin fastmcp, and the package has multiple published advisories, including auth and command-injection related issues. Because the actual installed version is unconstrained above a minimum, it is impossible to verify from this file whether deployments will avoid affected releases.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

Using an unpinned requests version means builds are not deterministic and may pull in newer releases with security regressions or ecosystem breakage. Because this skill appears to interact with remote services, dependency drift can affect both security posture and runtime behavior.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
fastmcp>=0.1.0
requests>=2.31.0
websockets>=12.0
python-dotenv>=1.0.0

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 known historical advisories, but the requirements file does not identify the exact installed version, so exposure cannot be assessed reliably. In a component that communicates with remote endpoints, unknown library versioning increases uncertainty around transport and credential-handling risks.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

An unpinned websockets dependency permits uncontrolled version selection at install time, which can expose the application to newly introduced flaws or unresolved known issues. This is especially relevant in a bridge component that likely relies on persistent network connections.

Content

Scanner excerpt · requirements.txt (reported line 3)May include surrounding context.

text
fastmcp>=0.1.0
requests>=2.31.0
websockets>=12.0
python-dotenv>=1.0.0

Unverifiable Dependency: websockets has 4 known advisory(ies) (CVE-2018-1000518 (websockets is vulnerable to denial of service by memory exhaustion); CVE-2021-33880 (Observable Timing Discrepancy in aaugustin websockets library); CVE-2018-1000518 (aaugustin websockets version 4 contains a CWE-409: Improper Handling of Highly C) +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
93% confidence
Finding

The websockets package has known denial-of-service and related advisories, and the unpinned requirement prevents verification that a safe version will be installed. Given this skill is an MCP bridge using websocket connectivity, affected versions could directly impact availability or connection security.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

The python-dotenv package is not pinned, so installations may vary across environments and over time. Even if the package is not directly exposed to attackers, uncontrolled dependency resolution increases supply-chain and operational risk.

Content

Scanner excerpt · requirements.txt (reported line 4)May include surrounding context.

text
fastmcp>=0.1.0
requests>=2.31.0
websockets>=12.0
python-dotenv>=1.0.0

Unverifiable Dependency: python-dotenv has 2 known advisory(ies) (CVE-2026-28684 (python-dotenv: Symlink following in set_key allows arbitrary file overwrite via ); CVE-2026-28684 (python-dotenv reads key-value pairs from a .env file and can set them as environ)), 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

python-dotenv has published advisories, and without an exact version the manifest cannot demonstrate whether installations are safe. While this dependency may be less exposed than networking libraries, unresolved version ambiguity still creates avoidable supply-chain and local file-handling risk.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.