Back to skill

Security audit

GLM MCP Server Use

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its stated GLM MCP setup purpose, but it needs review because it runs a mutable npm package and handles API keys in ways that can expose or persist them.

Review before installing. Use a low-scope Z.AI key, avoid passing it on the command line, protect or avoid committing generated mcporter configs, back up any existing config before setup, and prefer a pinned, audited @z_ai/mcp-server version or sandboxed execution for the vision server.

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)

T08 · Insecure Dependencies

Error
Location
scripts/setup_glm_mcp_servers.py:32
Finding

Unpinned npm Package Is Downloaded and Executed Automatically

Content
View full analysis
None: run([ "mcporter", "--config", config_path, "config", "add", "zai-vision", "--command", "npx", "--arg", "-y", "--arg", "@z_ai/mcp-server", "--env", f"Z_AI_API_KEY={api_key}", "--env", "Z_AI_MODE=ZAI", ]) ``` The same mutable invocation is documented in `SKILL.md:45`, `SKILL.md:89`, `references/official-endpoints.md:14`, and `references/test-report.md:42`: ```text npx -y @z_ai/mcp-server ``` ### Technical Analysis The configured vision server uses `npx -y` to retrieve and execute `@z_ai/mcp-server` without an exact version, lockfile, or verified integrity hash. Consequently, the code executed on a future invocation can differ from the code that was reviewed. The `-y` option suppresses installation confirmation, and the downloaded package is launched with the Z.AI API key in its environment. A compromised npm publisher account, registry response, package distribution process, or malicious future release could therefore turn a routine vision-server invocation into arbitrary local code execution. ### Attack Path 1. An attacker compromises the npm package publisher, package account, registry delivery path, or a future package release. 2. The attacker publishes malicious code under the version currently selected for `@z_ai/mcp-server`. 3. A user runs the setup workflow and later invokes the configured vision MCP server. 4. `npx -y` automatically retrieves and executes the mutable package release. 5. The malicious package executes with the user's operating-system privileges. 6. Because the process receives `Z_AI_API_KEY`, the package can read and disclose that credential in ...[truncated 743 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/get_zai_api_key.py:18
Finding

Z.AI API Key Can Be Exposed Through Standard Output and Process Arguments

Content
View full analysis
int: parser = argparse.ArgumentParser(description="Resolve Z.AI API key from environment variables") parser.add_argument("--masked", action="store_true", help="print masked value") args = parser.parse_args() key = get_key() if not key: return 1 if args.masked: if len(key) <= 8: print("*" * len(key)) else: print(f"{key[:4]}***{key[-4:]}") else: print(key) return 0 ``` The setup code places the credential in child-process arguments: ```python def add_http_server(config_path: str, name: str, url: str, api_key: str) -> None: run([ "mcporter", "--config", config_path, "config", "add", name, "--url", url, "--transport", "http", "--header", f"Authorization=Bearer {api_key}", ]) ``` ```python def add_vision_stdio(config_path: str, api_key: str) -> None: run([ "mcporter", "--config", config_path, "config", "add", "zai-vision", "--command", "npx", "--arg", "-y", "--arg", "@z_ai/mcp-server", "--env", f"Z_AI_API_KEY={api_key}", "--env", "Z_AI_MODE=ZAI", ]) ``` The setup interface also accepts the credential directly as a command-line argument: ```python parser.add_argument("--api-key", default=None, help="Z.AI API key (default: read from env vars)") ``` ### Technical Analysis Secure secret-handling interfaces should not reveal full credentials by default. Here, omi ...[truncated 1707 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/smoke_test_glm_mcp.py:51
Finding

Predictable Shared Temporary File Permits Symlink-Based File Overwrite

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (19)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill instructs use of environment variables, shell commands, and file-writing scripts, but it does not declare any explicit tool scope such as permissions or allowed-tools. This creates an authorization gap where an agent may execute higher-risk capabilities than a user expects, especially since the skill sets up remote MCP endpoints and writes configuration files.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

Using npx -y @z_ai/mcp-server without pinning a specific version causes code to be fetched and executed at runtime from the package registry. This introduces supply-chain risk: a compromised upstream package, malicious update, or dependency hijack could lead to arbitrary code execution in the agent environment.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

The document instructs users to run an unpinned npm package via npx, which fetches and executes the latest published code at runtime. If the package is compromised, typo-squatted, or updated with breaking or malicious behavior, users could execute untrusted code on their local system.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
89% confidence
Finding

The report documents use of npx -y @z_ai/mcp-server without a pinned package version, which can cause future executions to fetch whatever package version is current at runtime. If the upstream package is compromised, changed incompatibly, or a dependency is hijacked, anyone reproducing the documented command could execute unreviewed code, making this a real supply-chain risk even though it appears in test documentation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script prints the full API key to stdout by default when --masked is not supplied. Secrets written to stdout are commonly exposed through shell history, terminal scrollback, CI/CD logs, process wrappers, or downstream tooling, making accidental credential disclosure likely. In this skill context, the tool is specifically for configuring and troubleshooting MCP servers, which increases the chance it will be used in automated or shared environments where stdout is captured.

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 · scripts/setup_glm_mcp_servers.py (reported line 10)May include surrounding context.

python
def run(cmd: list[str]) -> None:
    result = subprocess.run(cmd, text=True, capture_output=True)
    if result.returncode != 0:
        raise RuntimeError((result.stderr or result.stdout).strip())

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script writes the API key directly into mcporter configuration as an HTTP Authorization header, which stores a reusable secret at rest. If that config file is later read by other users, checked into source control, or exposed via logs/backups, the credential can be stolen and used to access the external GLM services.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script embeds the API key in configured environment variables for the launched server process, which typically causes the secret to be persisted in configuration and inherited by that process. In this skill's MCP-server setup context, that increases the chance of credential exposure through config inspection, debugging output, or process-environment disclosure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script unconditionally deletes an existing config file unless --keep is provided, with no warning or confirmation. In a setup skill context, this can silently destroy prior configuration, potentially removing other server entries or security settings and causing denial of service or misconfiguration.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · SKILL.md (reported line 49)May include surrounding context.

md
if not api_key:
        raise SystemExit("No API key found. Set Z_AI_API_KEY (or ZAI_API_KEY/GLM_API_KEY/ZHIPU_API_KEY), or run with --api-key.")

    add_http_server(config_path, "web-search-prime", "https://api.z.ai/api/mcp/web_search_prime/mcp", api_key)
    add_http_server(config_path, "web-reader", "https://api.z.ai/api/mcp/web_reader/mcp", api_key)
    add_http_server(config_path, "zread", "https://api.z.ai/api/mcp/zread/mcp", api_key)
    add_vision_stdio(config_path, api_key)

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · SKILL.md (reported line 50)May include surrounding context.

md
if not api_key:
        raise SystemExit("No API key found. Set Z_AI_API_KEY (or ZAI_API_KEY/GLM_API_KEY/ZHIPU_API_KEY), or run with --api-key.")

    add_http_server(config_path, "web-search-prime", "https://api.z.ai/api/mcp/web_search_prime/mcp", api_key)
    add_http_server(config_path, "web-reader", "https://api.z.ai/api/mcp/web_reader/mcp", api_key)
    add_http_server(config_path, "zread", "https://api.z.ai/api/mcp/zread/mcp", api_key)
    add_vision_stdio(config_path, api_key)

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · SKILL.md (reported line 51)May include surrounding context.

md
if not api_key:
        raise SystemExit("No API key found. Set Z_AI_API_KEY (or ZAI_API_KEY/GLM_API_KEY/ZHIPU_API_KEY), or run with --api-key.")

    add_http_server(config_path, "web-search-prime", "https://api.z.ai/api/mcp/web_search_prime/mcp", api_key)
    add_http_server(config_path, "web-reader", "https://api.z.ai/api/mcp/web_reader/mcp", api_key)
    add_http_server(config_path, "zread", "https://api.z.ai/api/mcp/zread/mcp", api_key)
    add_vision_stdio(config_path, api_key)

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/official-endpoints.md (reported line 25)May include surrounding context.

md
if not api_key:
        raise SystemExit("No API key found. Set Z_AI_API_KEY (or ZAI_API_KEY/GLM_API_KEY/ZHIPU_API_KEY), or run with --api-key.")

    add_http_server(config_path, "web-search-prime", "https://api.z.ai/api/mcp/web_search_prime/mcp", api_key)
    add_http_server(config_path, "web-reader", "https://api.z.ai/api/mcp/web_reader/mcp", api_key)
    add_http_server(config_path, "zread", "https://api.z.ai/api/mcp/zread/mcp", api_key)
    add_vision_stdio(config_path, api_key)

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/official-endpoints.md (reported line 35)May include surrounding context.

md
if not api_key:
        raise SystemExit("No API key found. Set Z_AI_API_KEY (or ZAI_API_KEY/GLM_API_KEY/ZHIPU_API_KEY), or run with --api-key.")

    add_http_server(config_path, "web-search-prime", "https://api.z.ai/api/mcp/web_search_prime/mcp", api_key)
    add_http_server(config_path, "web-reader", "https://api.z.ai/api/mcp/web_reader/mcp", api_key)
    add_http_server(config_path, "zread", "https://api.z.ai/api/mcp/zread/mcp", api_key)
    add_vision_stdio(config_path, api_key)

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/official-endpoints.md (reported line 45)May include surrounding context.

md
if not api_key:
        raise SystemExit("No API key found. Set Z_AI_API_KEY (or ZAI_API_KEY/GLM_API_KEY/ZHIPU_API_KEY), or run with --api-key.")

    add_http_server(config_path, "web-search-prime", "https://api.z.ai/api/mcp/web_search_prime/mcp", api_key)
    add_http_server(config_path, "web-reader", "https://api.z.ai/api/mcp/web_reader/mcp", api_key)
    add_http_server(config_path, "zread", "https://api.z.ai/api/mcp/zread/mcp", api_key)
    add_vision_stdio(config_path, api_key)

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/setup_glm_mcp_servers.py (reported line 70)May include surrounding context.

python
if not api_key:
        raise SystemExit("No API key found. Set Z_AI_API_KEY (or ZAI_API_KEY/GLM_API_KEY/ZHIPU_API_KEY), or run with --api-key.")

    add_http_server(config_path, "web-search-prime", "https://api.z.ai/api/mcp/web_search_prime/mcp", api_key)
    add_http_server(config_path, "web-reader", "https://api.z.ai/api/mcp/web_reader/mcp", api_key)
    add_http_server(config_path, "zread", "https://api.z.ai/api/mcp/zread/mcp", api_key)
    add_vision_stdio(config_path, api_key)

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/setup_glm_mcp_servers.py (reported line 71)May include surrounding context.

python
if not api_key:
        raise SystemExit("No API key found. Set Z_AI_API_KEY (or ZAI_API_KEY/GLM_API_KEY/ZHIPU_API_KEY), or run with --api-key.")

    add_http_server(config_path, "web-search-prime", "https://api.z.ai/api/mcp/web_search_prime/mcp", api_key)
    add_http_server(config_path, "web-reader", "https://api.z.ai/api/mcp/web_reader/mcp", api_key)
    add_http_server(config_path, "zread", "https://api.z.ai/api/mcp/zread/mcp", api_key)
    add_vision_stdio(config_path, api_key)

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/setup_glm_mcp_servers.py (reported line 72)May include surrounding context.

python
if not api_key:
        raise SystemExit("No API key found. Set Z_AI_API_KEY (or ZAI_API_KEY/GLM_API_KEY/ZHIPU_API_KEY), or run with --api-key.")

    add_http_server(config_path, "web-search-prime", "https://api.z.ai/api/mcp/web_search_prime/mcp", api_key)
    add_http_server(config_path, "web-reader", "https://api.z.ai/api/mcp/web_reader/mcp", api_key)
    add_http_server(config_path, "zread", "https://api.z.ai/api/mcp/zread/mcp", api_key)
    add_vision_stdio(config_path, api_key)

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 · scripts/smoke_test_glm_mcp.py (reported line 18)May include surrounding context.

python
def run(cmd: list[str]) -> tuple[int, str]:
    r = subprocess.run(cmd, text=True, capture_output=True)
    out = (r.stdout or "") + ("\n" + r.stderr if r.stderr else "")
    return r.returncode, out.strip()

Static analysis

No suspicious patterns detected.