T09 · Insecure Skill Coding Practices
Error
- Location
- deploy.js:71
- Finding
- PowerShell Command Injection Through Unsafely Interpolated Deployment Parameters<![CDATA[ ## Vulnerability Details **File Location**: `deploy.js:71-83`, with attacker-controlled input selected at `deploy.js:133-134` **Vulnerability Type**: PowerShell command injection **Risk Level**: High ### Vulnerable Code ```javascript function generateDeployCommand(nodeId, targetDir) { const scriptsDir = targetDir; // Build PowerShell script let psScript = ` # node-transfer deployment script # Target: ${nodeId} # Directory: ${scriptsDir} $ErrorActionPreference = "Stop" # Create directory New-Item -ItemType Directory -Force -Path "${scriptsDir.replace(/\//g, '\\')}" | Out-Null `.trim(); ``` The values originate from command-line arguments or an environment variable: ```javascript const nodeId = args[0]; const targetDir = args[1] || process.env.TRANSFER_TARGET_DIR || 'C:/openclaw/skills/node-transfer/scripts'; ``` The same unescaped path is subsequently embedded in another executable PowerShell statement at `deploy.js:94-102`: ```javascript const targetPath = path.join(scriptsDir, file).replace(/\//g, '\\'); psScript += `\n\n`; psScript += `# Deploy ${file}\n`; psScript += `$b64 = "${encoded}"\n`; psScript += `[System.IO.File]::WriteAllBytes("${targetPath}", [System.Convert]::FromBase64String($b64))`; ``` ### Technical Analysis `nodeId`, the command-line `targetDir`, and `TRANSFER_TARGET_DIR` are inserted directly into generated PowerShell source without validation or PowerShell-safe quoting. A value containing a double quote, newline, statement separator, subexpression, or other PowerShell syntax can terminate the intended string or comment context and introduce additional commands. Replacing forward slashes with backslashes does not prevent command injection. The generated script is specifically intended to be sent to a remote node through `nodes.invoke`. Consequently, exploitation crosses from input manipulation on the orchestrating system to arbitrary command execution on the selected target node. The Base64 encoding it ...[truncated 1521 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Avoid constructing executable PowerShell through direct string interpolation. 2. Pass node identifiers and paths as separately encoded arguments rather than embedding them into source code. 3. Validate node identifiers using a strict allowlist appropriate to the OpenClaw node-ID format. 4. Resolve and constrain the deployment directory to approved installation roots. 5. Reject control characters, newlines, quotes, PowerShell metacharacters, and unsupported path forms. 6. If PowerShell source generation is unavoidable, implement and test a dedicated PowerShell literal encoder. Single-quoted PowerShell literals must escape each embedded single quote by doubling it. 7. Prefer a structured remote file-upload API over generated shell commands. 8. Require explicit confirmation of the target node and normalized destination before remote execution. 9. Add automated tests using paths containing quotes, semicolons, newlines, dollar signs, backticks, and PowerShell subexpressions. ]]>
