Back to skill

Security audit

WSL Windows Bridge

Security checks for vulnerabilities and agentic risk

Overview

This skill clearly discloses a Windows bridge purpose, but its installer creates persistent shell configuration from unescaped user input and enables powerful Windows command and file access with limited safety boundaries.

Install only if you intentionally want OpenClaw agents in WSL to execute Windows commands and read or write Windows-mounted files. Review setup.sh first, avoid pasting untrusted paths into setup, and prefer fixing the environment-file generation to shell-escape or validate paths before use.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/setup.sh:17
Finding
Shell Command Injection Through Generated Environment Configuration<![CDATA[ ## Vulnerability Details **File Location**: `scripts/setup.sh`, lines 17–27, 58–75, and 118 **Vulnerability Type**: Shell command injection through unsafe configuration generation **Risk Level**: High ### Vulnerable Code ```bash if [ -z "$DETECTED_WIN_ROOT" ]; then echo "WARNING: Could not auto-detect Windows Python. Please enter path manually." echo "" read -p "Windows root (e.g. D:\ or /mnt/d): " WIN_ROOT_INPUT WIN_ROOT="$WIN_ROOT_INPUT" else echo "Detected Windows root: $DETECTED_WIN_ROOT" WIN_ROOT="$DETECTED_WIN_ROOT" read -p "Python path [default: $WIN_ROOT/app/anaconda/python.exe]: " PYTHON_INPUT PYTHON_INPUT="${PYTHON_INPUT:-$WIN_ROOT/app/anaconda/python.exe}" fi if [[ "$PYTHON_INPUT" == /mnt/* ]]; then PYTHON_PATH="$PYTHON_INPUT" elif [[ "$PYTHON_INPUT" == /* ]]; then PYTHON_PATH=$(wslpath -w "$PYTHON_INPUT" 2>/dev/null || echo "$PYTHON_INPUT") else PYTHON_PATH="$PYTHON_INPUT" fi ``` ```bash cat > "$OPENCLAW_ENV" << ENVEOF #!/bin/bash # === wsl-windows-bridge environment === # Auto-generated at $(date -u +%Y-%m-%dT%H:%M:%SZ) export WIN_BIN="\$HOME/.openclaw/bin" export PATH="\$WIN_BIN:\$PATH" export WIN_ROOT="$WIN_ROOT" export WIN_ANACONDA="$WIN_ROOT/app/anaconda" export WIN_SCRIPTS="$WIN_ROOT/app/scripts" export WIN_PROJECT="$WIN_ROOT/app/project" export WIN_PYTHON="$PYTHON_PATH" export WIN_PS="/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe" export WIN_CMD="/mnt/c/Windows/System32/cmd.exe" ``` ```bash source "$OPENCLAW_ENV" 2>/dev/null ``` ### Technical Analysis The installer accepts an interactive Windows root or Python path and interpolates that value directly into an executable shell configuration file. No validation or shell-safe escaping is applied before constructing assignments such as: ```bash export WIN_ROOT="$WIN_ROOT" export WIN_PYTHON="$PYTHON_PATH" ``` An input containing a double quote followed by shell syntax can terminate the generated assignment and append ...[truncated 2077 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Use shell-safe serialization for generated assignments.** Generate every environment value with `printf %q` rather than embedding it in a heredoc: ```bash { printf '#!/bin/bash\n' printf 'export WIN_BIN=%q\n' "$HOME/.openclaw/bin" printf 'export PATH="$WIN_BIN:$PATH"\n' printf 'export WIN_ROOT=%q\n' "$WIN_ROOT" printf 'export WIN_ANACONDA=%q\n' "$WIN_ROOT/app/anaconda" printf 'export WIN_SCRIPTS=%q\n' "$WIN_ROOT/app/scripts" printf 'export WIN_PROJECT=%q\n' "$WIN_ROOT/app/project" printf 'export WIN_PYTHON=%q\n' "$PYTHON_PATH" printf 'export WIN_PS=%q\n' "/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe" printf 'export WIN_CMD=%q\n' "/mnt/c/Windows/System32/cmd.exe" } > "$OPENCLAW_ENV" ``` 2. **Validate input against expected path formats.** Reject control characters and values outside supported WSL or Windows path patterns. Validation should occur before writing the configuration: ```bash if [[ "$PYTHON_INPUT" == *$'\n'* || "$PYTHON_INPUT" == *$'\r'* ]]; then echo "ERROR: Path contains invalid control characters." >&2 exit 1 fi ``` A stricter allowlist should be used where practical. 3. **Do not immediately source generated executable configuration.** Perform verification using local variables or invoke tools directly after validation. This reduces the impact of any future serialization defect. 4. **Prefer a non-executable data format.** Store paths in a format such as JSON and load them with a parser instead of generating shell code from user input. 5. **Write the configuration atomically with restrictive permissions.** Create a temporary file using `mktemp`, set permissions to `0600`, validate its contents, and atomically rename it into place. ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (4)

Session Persistence

Medium
Category
Rogue Agent
Content
## What This Does

Provides six commands (`win-python`, `win-ps`, `win-cmd`, `win-copy`, `win-run-py`, `win-path`) that let OpenClaw agents running in WSL2 seamlessly call Windows Python, execute PowerShell/CMD commands, and read/write Windows files.

## Architecture
Confidence
60% 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.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The README explicitly advertises capabilities to execute Windows commands and read/write Windows files from WSL, but does not include any safety boundaries, permission expectations, or warnings about the system and data impact of using those commands. In a cross-boundary bridge skill, that omission materially increases the chance that an agent or user will use powerful primitives unsafely, leading to unintended file modification, command execution, or access to sensitive Windows-host resources.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill clearly exposes shell-capable wrappers that execute Windows PowerShell, CMD, and Python and can copy files across the WSL/Windows boundary, but it declares no explicit tool scope or permissions. That mismatch is dangerous because an agent or user may treat the skill as lower risk than it is, enabling arbitrary command execution and filesystem modification on the Windows host without an explicit trust boundary.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The setup and usage sections instruct users to install wrappers into ~/.openclaw/bin and use commands that can execute Windows PowerShell/CMD/Python and copy files into Windows paths, but they do not prominently warn about the resulting cross-system command execution and write capability. In this context, the omission increases the chance that an agent or operator will run the skill without understanding that it expands access from WSL into the Windows environment.

Static analysis

No suspicious patterns detected.