High severity7.8NVD Advisory· Published Apr 28, 2026· Updated May 1, 2026
CVE-2026-41384
CVE-2026-41384
Description
OpenClaw before 2026.3.24 contains an environment variable injection vulnerability in the CLI backend runner that allows attackers to inject malicious environment variables through workspace configuration. Attackers can craft malicious workspace configs to inject arbitrary environment variables into the backend process spawning, enabling code execution or sensitive data exposure.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
openclawnpm | < 2026.3.24 | 2026.3.24 |
Affected products
1Patches
1c2fb7f1948c3Adjust CLI backend environment handling before spawn (#53921)
2 files changed · +117 −2
src/agents/cli-runner.test.ts+111 −1 modified@@ -1,7 +1,7 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; -import { beforeEach, describe, expect, it, vi } from "vitest"; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import type { OpenClawConfig } from "../config/config.js"; import { resolveCliNoOutputTimeoutMs } from "./cli-runner/helpers.js"; import type { EmbeddedContextFile } from "./pi-embedded-helpers.js"; @@ -102,6 +102,10 @@ function createManagedRun(exit: MockRunExit, pid = 1234) { } describe("runCliAgent with process supervisor", () => { + afterEach(() => { + vi.unstubAllEnvs(); + }); + beforeEach(async () => { supervisorSpawnMock.mockClear(); enqueueSystemEventMock.mockClear(); @@ -157,6 +161,112 @@ describe("runCliAgent with process supervisor", () => { expect(input.scopeKey).toContain("thread-123"); }); + it("sanitizes dangerous backend env overrides before spawn", async () => { + vi.stubEnv("PATH", "/usr/bin:/bin"); + vi.stubEnv("HOME", "/tmp/trusted-home"); + + supervisorSpawnMock.mockResolvedValueOnce( + createManagedRun({ + reason: "exit", + exitCode: 0, + exitSignal: null, + durationMs: 50, + stdout: "ok", + stderr: "", + timedOut: false, + noOutputTimedOut: false, + }), + ); + + await runCliAgent({ + sessionId: "s1", + sessionFile: "/tmp/session.jsonl", + workspaceDir: "/tmp", + config: { + agents: { + defaults: { + cliBackends: { + "codex-cli": { + env: { + NODE_OPTIONS: "--require ./malicious.js", + LD_PRELOAD: "/tmp/pwn.so", + PATH: "/tmp/evil", + HOME: "/tmp/evil-home", + SAFE_KEY: "ok", + }, + }, + }, + }, + }, + } satisfies OpenClawConfig, + prompt: "hi", + provider: "codex-cli", + model: "gpt-5.2-codex", + timeoutMs: 1_000, + runId: "run-env-sanitized", + cliSessionId: "thread-123", + }); + + const input = supervisorSpawnMock.mock.calls[0]?.[0] as { + env?: Record<string, string | undefined>; + }; + expect(input.env?.SAFE_KEY).toBe("ok"); + expect(input.env?.PATH).toBe("/usr/bin:/bin"); + expect(input.env?.HOME).toBe("/tmp/trusted-home"); + expect(input.env?.NODE_OPTIONS).toBeUndefined(); + expect(input.env?.LD_PRELOAD).toBeUndefined(); + }); + + it("applies clearEnv after sanitizing backend env overrides", async () => { + vi.stubEnv("PATH", "/usr/bin:/bin"); + vi.stubEnv("SAFE_CLEAR", "from-base"); + + supervisorSpawnMock.mockResolvedValueOnce( + createManagedRun({ + reason: "exit", + exitCode: 0, + exitSignal: null, + durationMs: 50, + stdout: "ok", + stderr: "", + timedOut: false, + noOutputTimedOut: false, + }), + ); + + await runCliAgent({ + sessionId: "s1", + sessionFile: "/tmp/session.jsonl", + workspaceDir: "/tmp", + config: { + agents: { + defaults: { + cliBackends: { + "codex-cli": { + env: { + SAFE_KEEP: "keep-me", + }, + clearEnv: ["SAFE_CLEAR"], + }, + }, + }, + }, + } satisfies OpenClawConfig, + prompt: "hi", + provider: "codex-cli", + model: "gpt-5.2-codex", + timeoutMs: 1_000, + runId: "run-clear-env", + cliSessionId: "thread-123", + }); + + const input = supervisorSpawnMock.mock.calls[0]?.[0] as { + env?: Record<string, string | undefined>; + }; + expect(input.env?.SAFE_KEEP).toBe("keep-me"); + expect(input.env?.SAFE_CLEAR).toBeUndefined(); + }); + it("prepends bootstrap warnings to the CLI prompt body", async () => { supervisorSpawnMock.mockResolvedValueOnce( createManagedRun({
src/agents/cli-runner.ts+6 −1 modified@@ -5,6 +5,7 @@ import type { OpenClawConfig } from "../config/config.js"; import { shouldLogVerbose } from "../globals.js"; import { isTruthyEnvValue } from "../infra/env.js"; import { requestHeartbeatNow } from "../infra/heartbeat-wake.js"; +import { sanitizeHostExecEnv } from "../infra/host-env-security.js"; import { enqueueSystemEvent } from "../infra/system-events.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; import { getProcessSupervisor } from "../process/supervisor/index.js"; @@ -296,7 +297,11 @@ export async function runCliAgent(params: { } const env = (() => { - const next = { ...process.env, ...backend.env }; + const next = sanitizeHostExecEnv({ + baseEnv: process.env, + overrides: backend.env, + blockPathOverrides: true, + }); for (const key of backend.clearEnv ?? []) { delete next[key]; }
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/openclaw/openclaw/commit/c2fb7f1948c3226732a630256b5179a60664ec24nvdPatchWEB
- github.com/advisories/GHSA-vfw7-6rhc-6xxgghsaADVISORY
- github.com/openclaw/openclaw/security/advisories/GHSA-vfw7-6rhc-6xxgnvdVendor AdvisoryWEB
- nvd.nist.gov/vuln/detail/CVE-2026-41384ghsaADVISORY
- www.vulncheck.com/advisories/openclaw-environment-variable-injection-via-workspace-config-in-cli-backendnvdThird Party AdvisoryWEB
News mentions
0No linked articles in our index yet.