T09 · Insecure Skill Coding Practices
- Location
a2a-listener.py:296- Finding
Remote Command Injection Through Shell Command Template
- Content
View full analysis
tuple: """Run a custom shell command with {message} and {session_id} placeholders.""" cmd = cmd_template.replace("{message}", content.replace('"', '\\"')) cmd = cmd.replace("{session_id}", session_id.replace('"', '\\"')) log(f"INVOKING COMMAND: {cmd[:300]}") try: result = subprocess.run( cmd, shell=True, capture_output=True, text=True, timeout=timeout_secs ) ``` ### Technical Analysis The listener interpolates the remotely supplied task `content` and `session_id` into a configurable command and executes the resulting string with `shell=True`. Escaping only double quotation marks does not make input safe for a shell. Shell constructs such as command substitution using `$(...)` or backticks remain active inside double-quoted command arguments. The security of this code also depends on the surrounding syntax of the configurable template, making reliable escaping impractical. This behavior exceeds the minimum privileges needed to pass a message to OpenClaw. The safer CLI invocation elsewhere in the file already demonstrates that the message can be supplied as a distinct process argument without invoking a shell. ### Attack Path 1. The operator configures `A2A_OPENCLAW_COMMAND`, such as the command template documented by the Skill. 2. An attacker submits a task to `POST /v1/a2a/tasks/send`. 3. The task contains shell syntax in `message.content` or `sessionId`, such as a command substitution expression. 4. `_handle_task_send()` passes the attacker-controlled values to `_invoke_via_command()`. 5. The values are inserted into the command string. 6. `subprocess.run(..., shell=True)` passes the string to the system shell. ...[truncated 827 chars]- Remediation
View remediation
