Back to skill

Security audit

Homebrew Bridge

Security checks for vulnerabilities and agentic risk

Overview

The skill has a clear purpose, but its installer creates persistent SSH wrappers with unsafe host handling and file-writing behavior that users should review before installing.

Install only if you trust the OpenClaw config, the same-LAN Mac, and the target directory. Prefer an explicit normal user@host value, keep the wrapper target directory private and owned by the installing user, and avoid running the installer as root or against shared writable directories until host validation and symlink-safe file creation are added.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/install-wrapper.sh:19
Finding

SSH option injection through an unvalidated remote host

Content
View full analysis
/dev/null 2>&1; then local discovered discovered="$(python3 - "$OPENCLAW_CONFIG" <<'PY' import json import sys from pathlib import Path config_path = Path(sys.argv[1]) cfg = json.loads(config_path.read_text()) channels = cfg.get("channels") or {} hosts = [] for channel in channels.values(): if not isinstance(channel, dict): continue remote_host = channel.get("remoteHost") if isinstance(remote_host, str) and remote_host.strip(): host = remote_host.strip() if host not in hosts: hosts.append(host) if len(hosts) == 1: print(hosts[0]) PY )" ``` ```bash # scripts/install-homebrew-pack.sh default_host="$(discover_default_host || true)" for tool in "${REQUESTED_TOOLS[@]}"; do host="${TOOL_HOSTS[$tool]:-$default_host}" [[ -n "$host" ]] || { echo "missing host for tool: $tool" >&2 echo "Provide --map $tool=user@host or --default-host user@host." >&2 exit 1 } remote_bin="/opt/homebrew/bin/$tool" cmd=( "$INSTALL_WRAPPER" --name "$tool" --host "$host" --remote-bin "$remote_bin" --target-di ...[truncated 2399 chars]
Remediation
View remediation
&2 return 1 } [[ "$destination" =~ ^[A-Za-z0-9._-]+@[A-Za-z0-9.-]+$ ]] || { echo "Invalid SSH destination; expected user@host" >&2 return 1 } } validate_ssh_destination "$HOST" ``` The exact expression should be expanded deliberately if IPv6 or other SSH destination forms must be supported. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/install-wrapper.sh:45
Finding

Predictable wrapper installation follows existing symbolic links

Content
View full analysis
&2; exit 1; } [[ "$REMOTE_BIN" = /* ]] || { echo "remote-bin must be absolute" >&2; exit 1; } ``` ```bash mkdir -p "$TARGET_DIR" wrapper="$TARGET_DIR/$safe_name" ``` ```bash { cat < "$wrapper" chmod 755 "$wrapper" echo "Installed wrapper: $wrapper" ``` ### Technical Analysis The installer creates a predictable destination path and writes to it using ordinary shell redirection: ```bash } > "$wrapper" ``` It does not inspect the destination with `lstat`, reject an existing symbolic link, use exclusive creation, or create and atomically rename a secure temporary file. Shell redirection follows an existing symlink, so the generated wrapper content is written to the symlink target. The subsequent `chmod 755` can also affect the referenced target. This becomes a privilege-boundary vulnerability when an attacker can create entries in `TARGET_DIR` and a more privileged user later runs the installer. The attacker can place a symlink at the expected wrapper path and redirect the privileged write to another file that the installer account can modify. The wrapper-name handling introduces an additional collision concern. Invalid characters are si ...[truncated 1867 chars]
Remediation
View remediation
&2 exit 1 } safe_name="$NAME" ``` 2. Verify that the target directory is owned by the expected account and is not writable by less-privileged users. 3. Reject an existing symbolic link at the final destination using a non-following metadata check. 4. Generate the wrapper in a secure temporary file created with `mktemp` inside the target directory. 5. Set the temporary file's permissions before publication, then atomically rename it to the final destination. 6. Define an explicit replacement policy. If replacing an existing wrapper is allowed, verify that the existing object is a regular file with acceptable ownership before replacement. 7. Use a restrictive `umask`, such as `umask 077`, during temporary-file creation. 8. Add tests for existing symlinks, hard links where relevant, filename normalization collisions, attacker-writable target directories, and concurrent installation attempts. A safer installation structure is: ```bash [[ "$NAME" =~ ^[A-Za-z0-9._-]+$ ]] || exit 1 safe_name="$NAME" wrapper="$TARGET_DIR/$safe_name" mkdir -p -- "$TARGET_DIR" [[ ! -L "$wrapper" ]] || { echo "Refusing to replace symbolic link: $wrapper" >&2 exit 1 } umask 077 tmp="$(mktemp "$TARGET_DIR/.${safe_name}.tmp.XXXXXX")" trap 'rm -f -- "$tmp"' EXIT # Write generated wrapper content to "$tmp". chmod 755 -- "$tmp" # Before replacement, verify the destination state and ownership according to # the intended replacement policy. mv -- "$tmp" "$wrapper" trap - EXIT ``` For privileged deployments, directory ownership and permissions should also be validated immediately before the atomic rename to reduce race opportunities. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (4)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `scripts/install-wrapper.sh`: create one SSH wrapper for a remote binary

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill declares shell and file-read capable behavior in its documentation and workflow, but does not define an explicit tool scope such as permissions or allowed-tools. That creates an overbroad execution surface where an agent may invoke shell/file access more freely than intended, which is especially relevant here because the skill installs SSH wrappers, reads local OpenClaw config, and could influence remote command execution paths.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

This shell script writes another executable wrapper that will initiate SSH connections, send Wake-on-LAN network packets, and execute a remote binary. Although the generated wrapper logs one failure/retry message, the installer itself does not clearly warn the user that it is creating a script with these network and remote-execution behaviors before writing it to disk.

Content

No source excerpt is available for this finding.

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 · scripts/install-wrapper.sh (reported line 144)May include surrounding context.

sh
EOF
} > "$wrapper"

chmod 755 "$wrapper"
echo "Installed wrapper: $wrapper"

Static analysis

No suspicious patterns detected.