T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/progress_selfcheck_and_send.py:198
- Finding
- PowerShell Command Injection Through Report Content and Feishu Configuration<![CDATA[ ## Vulnerability Details **File Location**: `scripts/progress_selfcheck_and_send.py`, lines 198-212 **Vulnerability Type**: PowerShell command injection **Risk Level**: High ### Vulnerable Code ```python def _send_feishu(cfg: dict, message: str) -> None: if not cfg.get("feishu", {}).get("enabled", True): return account = cfg["feishu"]["account"] target = cfg["feishu"]["target"] safe = message.replace("`", "``") ps = ( "$m = @'\n" + safe + "\n'@; " + f"openclaw message send --channel feishu --account {account} --target {target} --message \"$m\"" ) cmd = ["powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", ps] workdir = Path(cfg["workdir"]) res = subprocess.run(cmd, cwd=str(workdir), capture_output=True, text=True, encoding="utf-8", errors="replace") ``` ### Technical Analysis The function constructs executable PowerShell source by concatenating report content and configuration values into a command string. Replacing backticks is not sufficient to secure a PowerShell single-quoted here-string. A line containing the here-string terminator `'@` can close `$m` before the intended boundary. Any text following that terminator can then be interpreted as PowerShell code. The `feishu.account` and `feishu.target` values are also inserted directly into the PowerShell command without quoting or strict validation. PowerShell metacharacters in either value can consequently alter the intended command. The generated report contains data read from several mutable sources: - Task titles and `next` commands from the task ledger - Progress-event messages - Cron job names and state - Feishu configuration values The relevant content is formatted into `message` in `scripts/progress_selfcheck_and_send.py`, lines 217-282, before being embedded in PowerShell source. Using `subprocess.run()` with an argument array does not prevent this vulnerability because PowerShell itself is explicitly i ...[truncated 1720 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Do not construct PowerShell source from report or configuration data. Invoke the `openclaw` executable directly and pass every value as a distinct process argument: ```python def _send_feishu(cfg: dict, message: str) -> None: feishu = cfg.get("feishu", {}) if not feishu.get("enabled", True): return account = feishu["account"] target = feishu["target"] cmd = [ "openclaw", "message", "send", "--channel", "feishu", "--account", account, "--target", target, "--message", message, ] workdir = Path(cfg["workdir"]) res = subprocess.run( cmd, cwd=str(workdir), capture_output=True, text=True, encoding="utf-8", errors="replace", shell=False, timeout=60, ) if res.returncode != 0: raise SystemExit( f"openclaw message send failed rc={res.returncode}: " f"{res.stderr.strip() or res.stdout.strip()}" ) ``` Additional hardening should include: 1. Validate `account` against a narrow identifier pattern suitable for configured OpenClaw accounts. 2. Validate `target` against the expected Feishu target syntax, such as a strict `user:ou_...` format. 3. Reject control characters in account and target fields. 4. Apply length limits to report fields to prevent resource exhaustion. 5. Avoid logging full command errors if they may expose sensitive message content. 6. Run the scheduled job under a dedicated, least-privileged account. 7. Add regression tests containing PowerShell metacharacters, newlines, quotes, and the `'@` here-string terminator. ]]>
