mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-27 06:50:40 +00:00
fix(exec): harden inherited host env sanitization (#25755) (thanks @bmendonca3)
This commit is contained in:
@@ -33,10 +33,12 @@ import { getShellConfig, sanitizeBinaryOutput } from "./shell-utils.js";
|
||||
// are not propagated into non-sandboxed executions.
|
||||
export function sanitizeHostBaseEnv(env: Record<string, string>): Record<string, string> {
|
||||
const sanitized: Record<string, string> = {};
|
||||
let hostPath: string | undefined;
|
||||
for (const [key, value] of Object.entries(env)) {
|
||||
const upperKey = key.toUpperCase();
|
||||
if (upperKey === "PATH") {
|
||||
sanitized[key] = value;
|
||||
// Canonicalize PATH casing so downstream PATH merges always hit one key.
|
||||
hostPath ??= value;
|
||||
continue;
|
||||
}
|
||||
if (isDangerousHostEnvVarName(upperKey)) {
|
||||
@@ -44,6 +46,9 @@ export function sanitizeHostBaseEnv(env: Record<string, string>): Record<string,
|
||||
}
|
||||
sanitized[key] = value;
|
||||
}
|
||||
if (hostPath !== undefined) {
|
||||
sanitized.PATH = hostPath;
|
||||
}
|
||||
return sanitized;
|
||||
}
|
||||
// Centralized sanitization helper.
|
||||
|
||||
@@ -4,6 +4,7 @@ import path from "node:path";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { ExecApprovalsResolved } from "../infra/exec-approvals.js";
|
||||
import { captureEnv } from "../test-utils/env.js";
|
||||
import { sanitizeHostBaseEnv } from "./bash-tools.exec-runtime.js";
|
||||
import { sanitizeBinaryOutput } from "./shell-utils.js";
|
||||
|
||||
const isWin = process.platform === "win32";
|
||||
@@ -155,6 +156,28 @@ describe("exec PATH login shell merge", () => {
|
||||
});
|
||||
|
||||
describe("exec host env validation", () => {
|
||||
it("sanitizes inherited host env without mutating source object", () => {
|
||||
const inherited = {
|
||||
PATH: "/usr/bin",
|
||||
Path: "/should-not-win",
|
||||
SAFE_KEY: "ok",
|
||||
LD_PRELOAD: "bad",
|
||||
sslkeylogfile: "/tmp/keys.log",
|
||||
};
|
||||
const sanitized = sanitizeHostBaseEnv(inherited);
|
||||
expect(sanitized).toEqual({
|
||||
PATH: "/usr/bin",
|
||||
SAFE_KEY: "ok",
|
||||
});
|
||||
expect(inherited).toEqual({
|
||||
PATH: "/usr/bin",
|
||||
Path: "/should-not-win",
|
||||
SAFE_KEY: "ok",
|
||||
LD_PRELOAD: "bad",
|
||||
sslkeylogfile: "/tmp/keys.log",
|
||||
});
|
||||
});
|
||||
|
||||
it("blocks LD_/DYLD_ env vars on host execution", async () => {
|
||||
const tool = createExecTool({ host: "gateway", security: "full", ask: "off" });
|
||||
|
||||
|
||||
Reference in New Issue
Block a user