Back to skill

Security audit

Setup Multi Gateway

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real multi-gateway setup wizard, but it ships unsafe credential handling and creates persistent services with unvalidated user-controlled values.

Review this skill carefully before installing. It should only be used on a machine where you are comfortable creating long-running OpenClaw user services, and you should not run the wizard with untrusted suggested values. Treat any generated model configs and Feishu configs as secret-bearing files, rotate the embedded API key if it is yours, avoid granting the broad Feishu scope bundle unless every permission is required, and prefer a fixed safe gateway name made only of letters, numbers, underscores, or hyphens.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (5)

T09 · Insecure Skill Coding Practices

Error
Location
mg-wizard.cjs:993
Finding

Shell Command Injection Through Unvalidated Interactive Input

Content
View full analysis
/dev/null | grep -i error || echo '暂无错误日志'`, { stdio: 'inherit' } ); const ssCheck = execSync( `ss -tlnp 2>/dev/null | grep ":${gatewayPort} " || true`, { encoding: 'utf8' } ); const netstatCheck = execSync( `netstat -tlnp 2>/dev/null | grep ":${gatewayPort} " || true`, { encoding: 'utf8' } ); ``` The pairing code and gateway name are also passed through a shell: ```js const pairingCode = await question('配对码(6 位数字): '); if (pairingCode && pairingCode.length >= 4) { console.log('\n正在提交配对码...'); try { const result = execSync( `openclaw pairing ${pairingCode.trim()} --agent ${gatewayName}`, { encoding: 'utf8', stdio: 'pipe' } ); log.success('配对成功!'); console.log(result); } catch (e) { log.warn('配对命令执行失败,请手动配对'); log.warn(`手动配对:openclaw pairing ${pairingCode.trim()} --agent ${gatewayName}`); } } ``` ### Technical Analysis `execSync()` invokes the command through a shell when supplied with a command string. The wizard inserts `gatewayName`, `gatewayPort`, and `pairingCode` directly into these command s ...[truncated 1766 chars]
Remediation
View remediation
65535) { throw new Error('Invalid gateway port'); } if (!/^\d{6}$/.test(pairingCode.trim())) { throw new Error('Invalid pairing code'); } ``` 3. Never concatenate interactive input into shell commands, even after generic escaping. 4. Pass log paths directly to filesystem APIs instead of invoking `tail` through a shell. 5. Add automated tests containing shell metacharacters, path separators, whitespace, and newlines. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
mg-wizard.cjs:879
Finding

Path Traversal and Persistent Systemd Unit Injection Through Gateway Metadata

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
mg-wizard.cjs:36
Finding

Hard-Coded API Key Is Distributed and Copied Into Generated Agent Configurations

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
mg-wizard.cjs:488
Finding

Predictable Gateway Tokens and Insecure Interactive Secret Handling

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
mg-wizard.cjs:1168
Finding

Overly Broad Session Visibility and Feishu Permission Guidance Violates Least Privilege

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (12)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

A hardcoded API key is embedded in the script and then injected into generated models.json files. Anyone with access to the script or generated configs can recover and abuse the credential, leading to unauthorized API usage, billing abuse, and possible access to upstream services under the owner's account.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill documentation is presented in Chinese from the title onward and does not indicate that users may choose another language or that alternative localized documentation exists. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation unless clearly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This markdown file presents all operational instructions and warnings in Chinese, but does not indicate that the skill is intended only for Chinese-speaking users or provide an opt-in language choice. Under the language/locale policy, forcing a specific language without user choice is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest’s user-facing description is entirely in Chinese, while nothing in the file indicates that the skill is explicitly region-specific or that users can opt into this locale. Under the policy, a forced language/locale without opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The wizard's prompts, instructions, and status messages are predominantly in Chinese, and the script does not offer the user any locale or language selection. This can violate language/locale policy when a specific language is imposed without opt-in or documented regional justification.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · mg-wizard.cjs (reported line 195)May include surrounding context.

js
try {
    if (createdResources.serviceFile && fs.existsSync(createdResources.serviceFile)) {
      execSync(`systemctl --user stop ${path.basename(createdResources.serviceFile, '.service')} 2>/dev/null || true`);
      execSync(`systemctl --user disable ${path.basename(createdResources.serviceFile, '.service')} 2>/dev/null || true`);
      fs.unlinkSync(createdResources.serviceFile);
      log.info(`已删除服务文件:${createdResources.serviceFile}`);

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · mg-wizard.cjs (reported line 196)May include surrounding context.

js
try {
    if (createdResources.serviceFile && fs.existsSync(createdResources.serviceFile)) {
      execSync(`systemctl --user stop ${path.basename(createdResources.serviceFile, '.service')} 2>/dev/null || true`);
      execSync(`systemctl --user disable ${path.basename(createdResources.serviceFile, '.service')} 2>/dev/null || true`);
      fs.unlinkSync(createdResources.serviceFile);
      log.info(`已删除服务文件:${createdResources.serviceFile}`);
    }

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The wizard collects a Feishu App Secret and writes it directly into a local config file without warning or protections. Storing long-lived secrets in plaintext increases the chance of credential theft through file disclosure, backups, logs, or multi-user host access.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

At L0611-L0614 the user-facing text says choosing option 3 means the gateway will be 'pure local use' and 'not bind any channel'. However, later the code still creates a systemd gateway service and may start it automatically (L0876-L0996), with port, token, basePath, and allowedOrigins configured earlier. That is an intent-level contradiction between the guidance text and the actual behavior.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The service file is created as 'openclaw-gateway-${gatewayName}.service' at L0882-L0902, but the drop-in directory for memory limits is written to '${gatewayName}.service.d' at L0955-L0965. The comments and log messages state the script is configuring memory limits for the created gateway service, yet the code writes the override under a mismatched unit name, contradicting the stated intent.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
91% confidence
Finding

The script enables a systemd user service for automatic restart across sessions, creating persistence on the host. In an agent skill context this is more sensitive because the script not only modifies local configuration but also installs a long-lived background service that continues running after the wizard exits.

Content

Scanner excerpt · mg-wizard.cjs (reported line 993)May include surrounding context.

js
const enableService = await question('是否现在启用并启动服务?[Y/n]: ');
    if (enableService.toLowerCase() !== 'n') {
      execSync(`systemctl --user enable openclaw-gateway-${gatewayName}.service`, { stdio: 'pipe' });
      log.success('启用服务');
      execSync(`systemctl --user start openclaw-gateway-${gatewayName}.service`, { stdio: 'pipe' });
      log.success('启动服务');

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

This changelog explicitly states the content was changed to Chinese ("更新 CHANGELOG 为中文", "添加中文 description", "完善中文说明") and the document itself is fully in Chinese. That indicates a language/locale constraint in the skill materials without any visible user choice or opt-in, which can violate language policy requirements.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.exposed_secret_literal

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
mg-wizard.cjs:53

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
mg-wizard.cjs:36