Back to skill

Security audit

connect-to-another-openclaw

Security checks for vulnerabilities and agentic risk

Overview

The skill is a disclosed remote OpenClaw admin tool, but unsafe defaults and command-construction bugs could let a compromised host or crafted skill list run commands locally or as root on the remote server.

Install only after review or fixes. Use a dedicated least-privilege SSH account and key, enable SSH host-key verification, avoid --yes, restrict targets to servers you own, validate and quote skill names before any local or remote install, and require explicit approval before killing processes or syncing skills.

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

T09 · Insecure Skill Coding Practices

Error
Location
main.py:235
Finding

Local Command Injection Through Remote-Controlled Skill Names

Content
View full analysis
&1 | tail -3") if result != 0: print(f" ⚠️ Installation may have failed") ``` ### Technical Analysis The value `s` is included directly in a command passed to `os.system()`. This API invokes a local shell, so shell metacharacters contained in the skill name are interpreted as command syntax rather than as part of a single argument. The skill names used by `sync-to-local` originate from the remote host's skill-directory listing. A compromised or malicious remote server can therefore influence the value reaching this command. Neither an allowlist nor shell escaping is applied. ### Attack Path 1. An attacker gains control of the configured remote host or its OpenClaw skills directory. 2. The attacker creates a skill entry whose filename contains shell syntax, such as a command separator followed by an attacker-selected command. 3. The operator invokes `sync-to-local`. 4. The malicious name is returned by `list_skills()` and included in `remote_only`. 5. The operator confirms the synchronization, or the command is run with `--yes`. 6. `os.system()` passes the constructed string to the local shell. 7. The injected command executes with the privileges of the local user running the skill. ### Impact Assessment Successful exploitation provides arbitrary command execution on the local OpenClaw machine. The attacker can access files available to the invoking account, modify the OpenClaw workspace, install additional software, steal credentials, or pivot to other systems. If the skill runs as root, the injected command receives full local administrative privileges. ]]>
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
main.py:130
Finding

Remote Command Injection Through Local Skill-List Entries

Content
View full analysis
dict: """Install a skill on remote via SkillHub""" rc, out, err = self.run("cd ~/.openclaw/workspace && ~/.local/bin/skillhub install " + skill_name) return {"rc": rc, "output": out, "error": err, "skill": skill_name} ``` ### Technical Analysis `skill_name` is concatenated directly into a command sent to SSH. The SSH server executes this command through the remote user's shell. Consequently, shell separators, substitutions, redirections, or other syntax in a skill-list entry are interpreted remotely. For `sync-to-remote`, names originate from the file selected through `--local-skills-file`. The implementation reads each nonempty line without validating it and later passes local-only entries to `install_skill()`. ### Attack Path 1. An attacker modifies the configured local skills-list file or convinces the operator to use an attacker-supplied file. 2. The attacker adds an entry containing shell metacharacters and an arbitrary command. 3. The operator invokes `sync-to-remote`. 4. `compare_skills()` classifies the crafted line as a local-only skill. 5. The operator confirms synchronization, or uses `--yes`. 6. `install_skill()` concatenates the entry into the SSH command. 7. The remote shell interprets and executes the injected payload as the configured SSH user. ### Impact Assessment Successful exploitation yields arbitrary command execution on the remote OpenClaw server. Because the default SSH user is `root`, the likely impact includes complete remote host compromise, modification of OpenClaw services and skills, credential access, data destruction, and use of the server for lateral movement. ]]>
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
main.py:22
Finding

SSH Host Authentication Disabled

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
main.py:16
Finding

Root-by-Default Administration and Overbroad Process Termination

Content
View full analysis
dict: """Kill common conflicting processes""" cmds = [ "pkill -f 'ssh -N.*18790' || true", "pkill -f 'voice-bridge-light' || true" ] results = [] for cmd in cmds: rc, out, err = self.run(cmd) results.append({"cmd": cmd, "rc": rc, "output": out}) return {"results": results} ``` ### Technical Analysis The application defaults to unrestricted remote root access even though status checks, listings, and log inspection generally do not require full administrative privileges. This magnifies the impact of every command-construction flaw. The `fix-port` action also uses broad `pkill -f` patterns. It does not verify that each matched process owns the conflicting port, belongs to OpenClaw, or is safe to terminate. The `voice-bridge-light` pattern is not even tied to port 18790. Once any port occupancy is detected, both termination commands are executed. ### Attack Path 1. The operator uses the default root SSH user and invokes `fix-port`. 2. Any output from the port-conflict check causes the conflict branch to run. 3. `pkill -f` searches the complete remote process command lines. 4. Every matching SSH tunnel for port 18790 and every matching `voice-bridge-light` process is terminated. 5. Unrelated services or administrative tunnels are disrupted. 6. The gateway is restarted afterward, also under root-level access. Separately, if a command-injection flaw is exploited during remote synchronization, the injected payload executes as root by default. ### Impact Assessment The direct impact is denial of service against unrelated processes and SSH tunnels. Root ...[truncated 304 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Error
Location
main.py:130
Finding

Unpinned Installation of Remotely Selected SkillHub Packages

Content
View full analysis
dict: """Install a skill on remote via SkillHub""" rc, out, err = self.run("cd ~/.openclaw/workspace && ~/.local/bin/skillhub install " + skill_name) return {"rc": rc, "output": out, "error": err, "skill": skill_name} ``` ```python if args.yes or input("Continue? (y/N): ").lower() == 'y': for s in to_install: print(f"Installing {s}...") result = os.system(f"skillhub install {s} 2>&1 | tail -3") if result != 0: print(f" ⚠️ Installation may have failed") ``` ### Technical Analysis Both synchronization directions install SkillHub packages using only a mutable package name. The implementation does not pin package versions or hashes and does not verify publisher identity, package signatures, resolved source, or an administrator-defined allowlist. For local synchronization, the package names are selected according to a remote server's directory listing. For remote synchronization, names come from a mutable local text file. Confirmation applies to the batch rather than providing verified provenance for each resolved package. ### Attack Path 1. An attacker controls a compared skill name, publishes or substitutes a package under that name, compromises the package source, or exploits a naming-confusion condition. 2. The package appears as missing on the synchronization destination. 3. The operator confirms the batch, or invokes the action with `--yes`. 4. SkillHub resolves the current package associated with the unpinned name. 5. The package is installed locally or remotely. 6. Any executable installation or runtime behavior supplied by the package runs in the destination environment. ### Impact Assessment A malicious or substituted package can execute arbitrary behavior w ...[truncated 320 chars]
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (24)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The declared description understates the skill's effective power: it not only checks status and syncs skills, but also kills remote processes, restarts services, tails logs, and can change software state on both local and remote systems. That mismatch can mislead users or supervising agents into authorizing a much more privileged and invasive capability set than intended.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Defaulting to a highly sensitive private key path and the root account normalizes use of powerful credentials for routine operations. In combination with remote shell actions and skill sync, this increases blast radius if the skill is misused, misconfigured, or tricked into connecting to an attacker-controlled host.

Content

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

md
| Variable | Purpose | Default |
|----------|---------|---------|
| `CONNECT_OPENCLAW_SSH_KEY` | Path to SSH private key | `~/.ssh/id_rsa` |
| `CONNECT_OPENCLAW_USER` | Remote username | `root` |
| `CONNECT_OPENCLAW_PORT` | SSH port | `22` |
| `CONNECT_OPENCLAW_GATEWAY_PORT` | Remote OpenClaw port | `18790` |

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 96)May include surrounding context.

md
from typing import Tuple, List, Optional

# Configuration defaults
DEFAULT_SSH_KEY = os.path.expanduser("~/.ssh/id_rsa")
DEFAULT_USER = "root"
DEFAULT_GATEWAY_PORT = 18790
DEFAULT_SSH_PORT = 22

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 106)May include surrounding context.

md
from typing import Tuple, List, Optional

# Configuration defaults
DEFAULT_SSH_KEY = os.path.expanduser("~/.ssh/id_rsa")
DEFAULT_USER = "root"
DEFAULT_GATEWAY_PORT = 18790
DEFAULT_SSH_PORT = 22

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · main.py (reported line 16)May include surrounding context.

python
from typing import Tuple, List, Optional

# Configuration defaults
DEFAULT_SSH_KEY = os.path.expanduser("~/.ssh/id_rsa")
DEFAULT_USER = "root"
DEFAULT_GATEWAY_PORT = 18790
DEFAULT_SSH_PORT = 22

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Confidence
99% confidence
Finding

This uses os.system with an f-string containing an untrusted skill name, causing direct shell command injection on the local machine. A malicious or compromised remote host can return crafted skill names via list_skills/compare_skills, and those names are later executed locally during sync-to-local.

Content

Scanner excerpt · main.py (reported line 242)May include surrounding context.

python
if args.yes or input("Continue? (y/N): ").lower() == 'y':
            for s in to_install:
                print(f"Installing {s}...")
                result = os.system(f"skillhub install {s} 2>&1 | tail -3")
                if result != 0:
                    print(f"  ⚠️  Installation may have failed")
            print("Done. Re-run with 'diff' to verify.")

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

Defaulting the SSH private key path to ~/.ssh/id_rsa encourages the skill to access a highly sensitive credential automatically, potentially using a user's primary SSH identity for remote administration. In a skill designed to connect to arbitrary remote hosts, this increases the blast radius of misuse and raises the risk of credential exposure, unintended key use, or privilege escalation across infrastructure.

Content

Scanner excerpt · skill.json (reported line 32)May include surrounding context.

json
{
      "name": "key",
      "type": "string",
      "default": "~/.ssh/id_rsa",
      "description": "Path to SSH private key"
    },
    {

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 106)May include surrounding context.

md
## Troubleshooting

### SSH Connection Fails
- Check key permissions: `chmod 600 ~/.ssh/id_rsa`
- Verify network: `ping host`
- Test manually: `ssh -i key host "echo ok"`
- If using password, switch to `ssh-agent` or use key

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

md
## Troubleshooting

### SSH Connection Fails
- Check key permissions: `chmod 600 ~/.ssh/id_rsa`
- Verify network: `ping host`
- Test manually: `ssh -i key host "echo ok"`
- If using password, switch to `ssh-agent` or use key

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill documents shell-capable operations over SSH but does not declare any explicit tool scope or permission boundaries. In a remote-administration skill, missing tool restrictions increases the chance that an agent can invoke broader shell actions than users expect, especially when the documented actions include process killing, log access, and skill installation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The documented fix-port workflow automatically kills processes and restarts the OpenClaw gateway without a prominent warning about service interruption or collateral impact. On a remote host, that can terminate legitimate tunnels or dependent services and cause avoidable downtime if triggered casually or by a mistaken diagnosis.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

The documentation advertises a --yes auto-confirm path for remote skill installation, enabling state-changing actions to proceed without human review. In a skill that can push software to another host, this increases the risk of unintended deployment, privilege misuse, or supply-chain spread if invoked by an automated agent or with incorrect targeting.

Content

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

md
- Always test with `--action test-connection` first
- `fix-port` will kill processes matching `ssh -N.*18790` and `voice-bridge-light`
- Skill sync uses SkillHub CLI; ensure it's installed on both sides
- For safety, `sync-to-remote` prompts before each installation (use `--yes` to auto-confirm)

---

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

SSH is configured with StrictHostKeyChecking=no, which disables server identity verification and makes man-in-the-middle interception feasible. Because this tool performs administrative actions and can synchronize software, a spoofed host could feed malicious data or receive privileged commands.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Disabling host key checking without surfacing that risk to the user weakens a core SSH safety control and hides a dangerous trust downgrade. Users may believe they are securely managing a known server while actually connecting to an attacker-controlled endpoint.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
88% confidence
Finding

The subprocess call itself is not unsafe because it passes an argument list to ssh, but the code appends a free-form remote command string that is executed by the remote shell. Several methods build that command with unsanitized values such as skill names and log filters, so an attacker controlling those values can trigger remote command injection on the target host, often as root.

Content

Scanner excerpt · main.py (reported line 33)May include surrounding context.

python
"""Run a remote command via SSH and return (returncode, stdout, stderr)"""
        full_cmd = self.ssh_base + [cmd]
        try:
            proc = subprocess.run(full_cmd, capture_output=True, text=True, timeout=timeout)
            return proc.returncode, proc.stdout, proc.stderr
        except subprocess.TimeoutExpired:
            return -1, "", f"SSH command timed out after {timeout}s"

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The skill goes beyond passive monitoring and synchronization by killing processes and restarting a gateway on the remote system. In a remote management tool this may be functional intent, but it materially increases the ability to disrupt services or interfere with unrelated processes if invoked against the wrong host or with overbroad patterns.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · main.py (reported line 155)May include surrounding context.

python
parser.add_argument("--local-skills-file", default="/root/.openclaw/workspace/local_skills.txt",
                        help="Local skills list file for diff action")
    parser.add_argument("--skill", help="Specific skill to install (used with sync-to-remote)")
    parser.add_argument("--yes", action="store_true", help="Auto-confirm prompts")

    args = parser.parse_args()

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The fix-port action kills remote processes and restarts the gateway immediately without a dedicated confirmation step. In an administrative tool this can cause avoidable denial of service or terminate the wrong processes, especially since the matching patterns are broad and the default remote user is root.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The manifest describes powerful remote-admin capabilities such as SSH access, health checks, port fixing, syncing, and monitoring, but it does not define meaningful activation constraints, target restrictions, or approval boundaries. In an agent ecosystem, broad descriptions for sensitive actions increase the chance the skill is invoked inappropriately or used on unintended hosts, enabling unauthorized administrative operations.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
82% confidence
Finding

This finding is substantively the same issue: automatic confirmation enables unattended execution of sensitive remote-admin actions. Because the skill manages other OpenClaw servers over SSH, removing interactive checks makes operational mistakes and abusive automation more dangerous than it would be in a read-only skill.

Content

Scanner excerpt · skill.json (reported line 50)May include surrounding context.

json
"name": "yes",
      "type": "boolean",
      "default": false,
      "description": "Auto-confirm prompts without asking"
    }
  ],
  "environment": {

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

This finding is substantively the same issue: automatic confirmation enables unattended execution of sensitive remote-admin actions. Because the skill manages other OpenClaw servers over SSH, removing interactive checks makes operational mistakes and abusive automation more dangerous than it would be in a read-only skill.

Content

Scanner excerpt · skill.json (reported line 50)May include surrounding context.

json
"name": "yes",
      "type": "boolean",
      "default": false,
      "description": "Auto-confirm prompts without asking"
    }
  ],
  "environment": {

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

Line L003 presents the skill description in Chinese while the rest of the document is in English, and there is no note that the skill is region-specific or that users may choose their preferred language. This creates a natural-language locale policy concern because the file imposes a language choice without opt-in or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

The author field contains Chinese text (基于 2026-03-28 实践经验) in an otherwise English document. This introduces a language-specific element without opt-in or explanation, which can conflict with organizational language/locale consistency expectations.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
71% confidence
Finding

The author field uses a specific non-English locale representation ('小李'), which may indicate a locale-specific convention in the skill metadata without any documented language or locale choice for users. Because this file contains natural-language metadata only, the concern is limited, but there is no explicit opt-in or justification for locale expectations anywhere in the manifest.

Content

No source excerpt is available for this finding.