@rtk-ai/rtk-rewrite: OpenClaw Rewrite Plugin Command Injection via execSync Template String
Description
@rtk-ai/rtk-rewrite transparently rewrites shell commands executed via OpenClaw's exec tool to their RTK equivalents. In 1.0.0, the @rtk-ai/rtk-rewrite OpenClaw plugin passes attacker-controlled input directly into a shell-backed execSync() template string without shell-safe escaping. JSON.stringify() wraps the value in double quotes and escapes inner double-quotes and backslashes, but leaves $() and backtick shell metacharacters untouched. Because execSync delegates execution to /bin/sh -c, the shell expands $(...) substitutions even inside double-quoted strings, causing the injected subcommand to execute before rtk is invoked. An attacker who can influence the exec tool's command parameter (e.g., via an LLM agent prompt or gateway/tool-call input) achieves arbitrary OS command execution with the privileges of the plugin/gateway process.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Affected products
1Patches
Vulnerability mechanics
Root cause
"Missing shell-safe escaping in execSync() template string allows $() shell metacharacter expansion inside double-quoted strings."
Attack vector
An attacker who can influence the `exec` tool's `command` parameter — for example via an LLM agent prompt, a malicious prompt injected into agent context, or a direct tool-call request — achieves arbitrary OS command execution. `JSON.stringify()` wraps the value in double quotes and escapes inner double-quotes and backslashes, but leaves `$()` and backtick shell metacharacters untouched. Because `execSync` delegates execution to `/bin/sh -c`, the shell expands `$(...)` substitutions even inside double-quoted strings, causing the injected subcommand to execute before `rtk` is invoked [ref_id=1]. The plugin is enabled by default after installation, and no authentication logic exists within the plugin code itself.
Affected code
The vulnerable sink is `openclaw/index.ts:29` where `execSync(\`rtk rewrite ${JSON.stringify(command)}\`, ...)` passes attacker-controlled input into a shell-backed template string. The taint flow begins at `openclaw/index.ts:56` where the `command` parameter is extracted from `event.params?.command` in a `before_tool_call` hook, then forwarded through `tryRewrite()` without shell metacharacter validation.
What the fix does
The patch replaces `execSync` with `spawnSync` using an argument array and `shell: false`, which prevents the shell from interpreting metacharacters. The `checkRtk()` function is also changed from `execSync("which rtk")` to `spawnSync("rtk", ["--version"], { shell: false })`, eliminating the shell invocation entirely. With `shell: false`, the `rtk` binary is executed directly and the `command` string is passed as a literal argument, so `$()` and backtick sequences are never expanded.
Preconditions
- inputAttacker must be able to supply an arbitrary string as the exec tool's command parameter (e.g., via LLM agent prompt, gateway/tool-call input, or malicious prompt injection)
- configThe @rtk-ai/rtk-rewrite OpenClaw plugin must be installed and enabled (enabled by default)
Reproduction
The advisory provides a full reproduction via Docker. Build the image with `docker build -t rtk-vuln-001-cwe78 /path/to/vuln-001/` using the provided Dockerfile, then run `docker run --rm --network none rtk-vuln-001-cwe78`. The container stdout confirms the attack chain: `POC_FILE_CREATED` and `COMMAND INJECTION CONFIRMED` are printed. An inline reproduction without Docker is also provided using `node -` with the vulnerable `execSync` pattern.
Generated on Jun 24, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
1- github.com/rtk-ai/rtk/security/advisories/GHSA-fqgj-m2gp-mr3qmitrex_refsource_CONFIRM
News mentions
0No linked articles in our index yet.