Mar 3, 2026·6 min read·2 visits
OpenClaw < 2026.2.26 allows execution approval bypass via loose context binding. Attackers can reuse approved command IDs with modified environment variables to achieve arbitrary code execution.
A critical context-binding weakness in the OpenClaw AI assistant platform allows attackers to bypass human-in-the-loop approval controls. Specifically, the `system.run` workflow in the Node host environment fails to cryptographically bind user approvals to the exact execution context, including environment variables and command arguments. This flaw permits an attacker to hijack a legitimate approval ID and reuse it to execute arbitrary code by injecting malicious environment variables (e.g., `GIT_EXTERNAL_DIFF`) or modifying arguments, effectively nullifying the security guarantees of the approval system.
The OpenClaw platform, designed as a personal AI assistant, includes a system.run capability that allows agents to execute shell commands on the host machine. To prevent unauthorized actions, this capability is governed by a human-in-the-loop approval workflow, particularly in host=node configurations. When an agent requests to run a command, the user must explicitly grant permission, generating a unique approval identifier associated with that specific request. This mechanism is intended to act as a security gate, ensuring that high-risk operations cannot proceed without user consent.
However, a vulnerability exists in how these approval identifiers are bound to the execution context. In affected versions, the binding mechanism relies on a loose association that primarily validates the command string but fails to enforce strict integrity over the entire runtime environment. This oversight means that the approval record does not cryptographically seal the command arguments (argv), the working directory (cwd), or, most critically, the environment variables (env) present at the time of the request.
The absence of strict context binding creates a race condition-like flaw where the parameters of an approved action can be swapped between the time of approval and the time of execution. While the system correctly verifies that a valid approval ID exists for the command being requested, it does not verify that the environment in which the command runs matches the environment the user approved. This discrepancy opens the door for environment variable injection attacks.
The root cause of this vulnerability is the use of a weak integrity binding between the approval artifact and the execution parameters. Specifically, the system utilized a legacy matching logic (matchLegacySystemRunApprovalBinding) that prioritized availability over strict security. This legacy logic performed a superficial check, ensuring that the requested command (e.g., git) matched the approved command, but it disregarded the volatile state of the execution environment.
In POSIX environments, the behavior of many binaries is heavily influenced by environment variables. For example, the git command's behavior can be fundamentally altered by variables such as GIT_EXTERNAL_DIFF or GIT_SSH_COMMAND, which can be used to execute arbitrary scripts. By failing to include a hash of the environment variables in the approval signature, OpenClaw treated an execution request for git status with a clean environment as identical to a request for git status with a malicious environment payload.
Additionally, the system failed to enforce canonicalization of the command arguments. The reliance on simple text matching rather than structured argv array comparison meant that subtle manipulations of arguments—such as inserting flag delimiters or leveraging shell expansion quirks—could potentially pass the approval check while altering the command's actual logic. This represents a failure to adhere to CWE-345 (Insufficient Verification of Data Authenticity) and CWE-1385 (Missing Verification in Workflow).
The vulnerability resides in the src/gateway/node-invoke-system-run-approval-match.ts module, where the system validates whether a pending execution request matches a stored approval. Prior to the patch, the code allowed a fallback to a legacy matching function that lacked environment verification.
The fix introduces a strict verification protocol known as systemRunBindingV1. This new binding schema requires that every aspect of the execution context be hashed and compared. The following pseudocode illustrates the logic flow before and after the patch:
Vulnerable Logic (Simplified):
function validateApproval(request, approval) {
// VULNERABLE: Only checks if the command string matches
if (request.command === approval.command) {
return true;
}
return false;
}Patched Logic (Secure):
import { hashEnv } from './crypto-utils';
function validateApproval(request, approval) {
// SECURE: Enforces V1 binding with environment hashing
const currentEnvHash = hashEnv(request.env);
if (approval.version !== 'v1') {
throw new Error('Legacy approvals no longer supported');
}
// Check 1: Strict Argv Matching
if (!deepEqual(request.argv, approval.argv)) {
return false;
}
// Check 2: Environment Integrity
if (currentEnvHash !== approval.envHash) {
return false; // Blocks Env Injection
}
return true;
}The patch (Commit 10481097f8e6dd0346db9be0b5f27570e1bdfcfa) explicitly removes the matchLegacySystemRunApprovalBinding function and enforces the matchSystemRunApprovalBindingV1 logic. It also introduces an environment blocklist for host=node flows, proactively filtering dangerous variables before they even reach the approval stage.
To exploit this vulnerability, an attacker typically requires the ability to interact with the OpenClaw agent interface or compromise a low-privileged component that can request command execution. The attack vector focuses on hijacking a legitimate approval to piggyback malicious payloads.
Scenario: Environment Injection via Git
git status. This is a benign command that the user is likely to approve.approvalId.approvalId. They then construct a new execution request using the same approvalId and the same command git status, but they inject the environment variable GIT_EXTERNAL_DIFF=/tmp/malicious_script.sh.approvalId is valid and the command is git status. It permits the execution.git initializes, it detects the GIT_EXTERNAL_DIFF variable and executes /tmp/malicious_script.sh with the privileges of the host process, achieving arbitrary code execution.This technique circumvents the core security promise of the tool. The user believes they authorized a safe read-only operation, but the lack of context binding allows the attacker to transmute that authorization into a full system compromise.
The impact of this vulnerability is significant for users relying on OpenClaw's approval mechanisms to secure their local environments. A successful exploit allows for Arbitrary Code Execution (ACE) on the host machine running the Node agent. Since personal AI assistants often run with the user's personal privileges (which typically include access to SSH keys, cloud credentials, and sensitive documents), the compromise is equivalent to a full user account takeover.
The vulnerability neutralizes the "Human-in-the-Loop" security control. Organizations or individuals utilizing host=node flows under the assumption that they are protected by manual approval are effectively unprotected against malicious modifications of approved commands. The CVSS score is moderated only by the requirement that the attacker must already have a way to submit execution requests or compromise the agent's internal message bus to reuse the approval ID.
CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
OpenClaw OpenClaw | < 2026.2.26 | 2026.2.26 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-345 |
| CVSS Score | 6.5 |
| Attack Vector | Local / Adjacent |
| Vulnerability Type | Context Binding Weakness |
| Affected Component | system.run |
| Exploit Status | PoC Available (Internal) |
Insufficient Verification of Data Authenticity