mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-02 02:00:23 +00:00
@@ -22,6 +22,8 @@
|
||||
"CC",
|
||||
"CXX",
|
||||
"CARGO_BUILD_RUSTC",
|
||||
"CARGO_BUILD_RUSTC_WRAPPER",
|
||||
"RUSTC_WRAPPER",
|
||||
"CMAKE_C_COMPILER",
|
||||
"CMAKE_CXX_COMPILER",
|
||||
"SHELL",
|
||||
@@ -38,9 +40,12 @@
|
||||
"DOTNET_ADDITIONAL_DEPS",
|
||||
"GLIBC_TUNABLES",
|
||||
"MAVEN_OPTS",
|
||||
"MAKEFLAGS",
|
||||
"MFLAGS",
|
||||
"SBT_OPTS",
|
||||
"GRADLE_OPTS",
|
||||
"ANT_OPTS"
|
||||
"ANT_OPTS",
|
||||
"HGRCPATH"
|
||||
],
|
||||
"blockedOverrideKeys": [
|
||||
"HOME",
|
||||
@@ -76,6 +81,8 @@
|
||||
"CGO_CFLAGS",
|
||||
"CGO_LDFLAGS",
|
||||
"GOFLAGS",
|
||||
"MAKEFLAGS",
|
||||
"MFLAGS",
|
||||
"CORECLR_PROFILER_PATH",
|
||||
"PHPRC",
|
||||
"PHP_INI_SCAN_DIR",
|
||||
@@ -127,7 +134,9 @@
|
||||
"GOPRIVATE",
|
||||
"GOENV",
|
||||
"GOPATH",
|
||||
"HGRCPATH",
|
||||
"PYTHONUSERBASE",
|
||||
"RUSTC_WRAPPER",
|
||||
"VIRTUAL_ENV",
|
||||
"LUA_PATH",
|
||||
"LUA_CPATH",
|
||||
@@ -135,6 +144,7 @@
|
||||
"GEM_PATH",
|
||||
"BUNDLE_GEMFILE",
|
||||
"COMPOSER_HOME",
|
||||
"CARGO_BUILD_RUSTC_WRAPPER",
|
||||
"XDG_CONFIG_HOME",
|
||||
"AWS_CONFIG_FILE"
|
||||
],
|
||||
|
||||
@@ -143,10 +143,14 @@ describe("isDangerousHostEnvVarName", () => {
|
||||
expect(isDangerousHostEnvVarName("cxx")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("CARGO_BUILD_RUSTC")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("cargo_build_rustc")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("CARGO_BUILD_RUSTC_WRAPPER")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("cargo_build_rustc_wrapper")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("CMAKE_C_COMPILER")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("cmake_c_compiler")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("CMAKE_CXX_COMPILER")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("cmake_cxx_compiler")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("RUSTC_WRAPPER")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("rustc_wrapper")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("SHELLOPTS")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("ps4")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("DYLD_INSERT_LIBRARIES")).toBe(true);
|
||||
@@ -168,12 +172,18 @@ describe("isDangerousHostEnvVarName", () => {
|
||||
expect(isDangerousHostEnvVarName("glibc_tunables")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("MAVEN_OPTS")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("maven_opts")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("MAKEFLAGS")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("makeflags")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("MFLAGS")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("mflags")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("SBT_OPTS")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("sbt_opts")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("GRADLE_OPTS")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("gradle_opts")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("ANT_OPTS")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("ant_opts")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("HGRCPATH")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("hgrcpath")).toBe(true);
|
||||
expect(isDangerousHostEnvVarName("HTTPS_PROXY")).toBe(false);
|
||||
expect(isDangerousHostEnvVarName("https_proxy")).toBe(false);
|
||||
expect(isDangerousHostEnvVarName("HTTP_PROXY")).toBe(false);
|
||||
@@ -210,6 +220,11 @@ describe("sanitizeHostExecEnv", () => {
|
||||
GIT_EXTERNAL_DIFF: "/tmp/pwn.sh",
|
||||
GIT_TEMPLATE_DIR: "/tmp/git-template",
|
||||
GIT_SEQUENCE_EDITOR: "/tmp/pwn-sequence-editor",
|
||||
HGRCPATH: "/tmp/evil-hgrc",
|
||||
CARGO_BUILD_RUSTC_WRAPPER: "/tmp/evil-rustc-wrapper",
|
||||
RUSTC_WRAPPER: "/tmp/evil-rustc-wrapper",
|
||||
MAKEFLAGS: "--eval=$(shell touch /tmp/pwned)",
|
||||
MFLAGS: "--eval=$(shell touch /tmp/pwned-too)",
|
||||
AWS_CONFIG_FILE: "/tmp/aws-config",
|
||||
LD_PRELOAD: "/tmp/pwn.so",
|
||||
OK: "1",
|
||||
@@ -242,8 +257,11 @@ describe("sanitizeHostExecEnv", () => {
|
||||
CC: "/tmp/evil-cc",
|
||||
CXX: "/tmp/evil-cxx",
|
||||
CARGO_BUILD_RUSTC: "/tmp/evil-rustc",
|
||||
CARGO_BUILD_RUSTC_WRAPPER: "/tmp/evil-rustc-wrapper",
|
||||
CMAKE_C_COMPILER: "/tmp/evil-c-compiler",
|
||||
CMAKE_CXX_COMPILER: "/tmp/evil-cxx-compiler",
|
||||
RUSTC_WRAPPER: "/tmp/evil-rustc-wrapper",
|
||||
HGRCPATH: "/tmp/evil-hgrc",
|
||||
GIT_SSH_COMMAND: "touch /tmp/pwned",
|
||||
GIT_EDITOR: "/tmp/git-editor",
|
||||
GIT_EXEC_PATH: "/tmp/git-exec-path",
|
||||
@@ -295,6 +313,8 @@ describe("sanitizeHostExecEnv", () => {
|
||||
PS4: "$(touch /tmp/pwned)",
|
||||
CLASSPATH: "/tmp/evil-classpath",
|
||||
GOFLAGS: "-mod=mod",
|
||||
MAKEFLAGS: "--eval=$(shell touch /tmp/pwned)",
|
||||
MFLAGS: "--eval=$(shell touch /tmp/pwned-too)",
|
||||
PHPRC: "/tmp/evil-php.ini",
|
||||
XDG_CONFIG_HOME: "/tmp/evil-config",
|
||||
SAFE: "ok",
|
||||
@@ -309,8 +329,11 @@ describe("sanitizeHostExecEnv", () => {
|
||||
expect(env.CC).toBeUndefined();
|
||||
expect(env.CXX).toBeUndefined();
|
||||
expect(env.CARGO_BUILD_RUSTC).toBeUndefined();
|
||||
expect(env.CARGO_BUILD_RUSTC_WRAPPER).toBeUndefined();
|
||||
expect(env.CMAKE_C_COMPILER).toBeUndefined();
|
||||
expect(env.CMAKE_CXX_COMPILER).toBeUndefined();
|
||||
expect(env.RUSTC_WRAPPER).toBeUndefined();
|
||||
expect(env.HGRCPATH).toBeUndefined();
|
||||
expect(env.GIT_TEMPLATE_DIR).toBeUndefined();
|
||||
expect(env.GIT_SEQUENCE_EDITOR).toBeUndefined();
|
||||
expect(env.AWS_CONFIG_FILE).toBeUndefined();
|
||||
@@ -324,6 +347,8 @@ describe("sanitizeHostExecEnv", () => {
|
||||
expect(env.PS4).toBeUndefined();
|
||||
expect(env.CLASSPATH).toBeUndefined();
|
||||
expect(env.GOFLAGS).toBeUndefined();
|
||||
expect(env.MAKEFLAGS).toBeUndefined();
|
||||
expect(env.MFLAGS).toBeUndefined();
|
||||
expect(env.PHPRC).toBeUndefined();
|
||||
expect(env.XDG_CONFIG_HOME).toBeUndefined();
|
||||
expect(env.YARN_RC_FILENAME).toBe(".trusted-yarnrc.yml");
|
||||
@@ -524,8 +549,18 @@ describe("isDangerousHostEnvOverrideVarName", () => {
|
||||
expect(isDangerousHostEnvOverrideVarName("virtual_env")).toBe(true);
|
||||
expect(isDangerousHostEnvOverrideVarName("CLASSPATH")).toBe(true);
|
||||
expect(isDangerousHostEnvOverrideVarName("classpath")).toBe(true);
|
||||
expect(isDangerousHostEnvOverrideVarName("MAKEFLAGS")).toBe(true);
|
||||
expect(isDangerousHostEnvOverrideVarName("makeflags")).toBe(true);
|
||||
expect(isDangerousHostEnvOverrideVarName("MFLAGS")).toBe(true);
|
||||
expect(isDangerousHostEnvOverrideVarName("mflags")).toBe(true);
|
||||
expect(isDangerousHostEnvOverrideVarName("GOFLAGS")).toBe(true);
|
||||
expect(isDangerousHostEnvOverrideVarName("goflags")).toBe(true);
|
||||
expect(isDangerousHostEnvOverrideVarName("HGRCPATH")).toBe(true);
|
||||
expect(isDangerousHostEnvOverrideVarName("hgrcpath")).toBe(true);
|
||||
expect(isDangerousHostEnvOverrideVarName("RUSTC_WRAPPER")).toBe(true);
|
||||
expect(isDangerousHostEnvOverrideVarName("rustc_wrapper")).toBe(true);
|
||||
expect(isDangerousHostEnvOverrideVarName("CARGO_BUILD_RUSTC_WRAPPER")).toBe(true);
|
||||
expect(isDangerousHostEnvOverrideVarName("cargo_build_rustc_wrapper")).toBe(true);
|
||||
expect(isDangerousHostEnvOverrideVarName("CORECLR_PROFILER_PATH")).toBe(true);
|
||||
expect(isDangerousHostEnvOverrideVarName("coreclr_profiler_path")).toBe(true);
|
||||
expect(isDangerousHostEnvOverrideVarName("XDG_CONFIG_HOME")).toBe(true);
|
||||
@@ -547,6 +582,7 @@ describe("sanitizeHostExecEnvWithDiagnostics", () => {
|
||||
overrides: {
|
||||
PATH: "/tmp/evil",
|
||||
CXX: "/tmp/evil-cxx",
|
||||
CARGO_BUILD_RUSTC_WRAPPER: "/tmp/evil-rustc-wrapper",
|
||||
CARGO_REGISTRIES_CRATES_IO_INDEX: "https://example.invalid/crates.io-index",
|
||||
CMAKE_C_COMPILER: "/tmp/evil-c-compiler",
|
||||
CLASSPATH: "/tmp/evil-classpath",
|
||||
@@ -582,7 +618,11 @@ describe("sanitizeHostExecEnvWithDiagnostics", () => {
|
||||
GOPRIVATE: "example.invalid/*",
|
||||
GOENV: "/tmp/evil-goenv",
|
||||
GOPATH: "/tmp/evil-go",
|
||||
HGRCPATH: "/tmp/evil-hgrc",
|
||||
MAKEFLAGS: "--eval=$(shell touch /tmp/pwned)",
|
||||
MFLAGS: "--eval=$(shell touch /tmp/pwned-too)",
|
||||
PYTHONUSERBASE: "/tmp/evil-python-userbase",
|
||||
RUSTC_WRAPPER: "/tmp/evil-rustc-wrapper",
|
||||
VIRTUAL_ENV: "/tmp/evil-venv",
|
||||
YARN_RC_FILENAME: ".evil-yarnrc.yml",
|
||||
HTTPS_PROXY: "http://proxy.example.test:8080",
|
||||
@@ -597,6 +637,7 @@ describe("sanitizeHostExecEnvWithDiagnostics", () => {
|
||||
|
||||
expect(result.rejectedOverrideBlockedKeys).toEqual([
|
||||
"C_INCLUDE_PATH",
|
||||
"CARGO_BUILD_RUSTC_WRAPPER",
|
||||
"CARGO_REGISTRIES_CRATES_IO_INDEX",
|
||||
"CLASSPATH",
|
||||
"CMAKE_C_COMPILER",
|
||||
@@ -618,8 +659,11 @@ describe("sanitizeHostExecEnvWithDiagnostics", () => {
|
||||
"GOPATH",
|
||||
"GOPRIVATE",
|
||||
"GOPROXY",
|
||||
"HGRCPATH",
|
||||
"HTTPS_PROXY",
|
||||
"LIBRARY_PATH",
|
||||
"MAKEFLAGS",
|
||||
"MFLAGS",
|
||||
"NODE_EXTRA_CA_CERTS",
|
||||
"NODE_TLS_REJECT_UNAUTHORIZED",
|
||||
"OBJC_INCLUDE_PATH",
|
||||
@@ -632,6 +676,7 @@ describe("sanitizeHostExecEnvWithDiagnostics", () => {
|
||||
"PIP_TRUSTED_HOST",
|
||||
"PYTHONUSERBASE",
|
||||
"REQUESTS_CA_BUNDLE",
|
||||
"RUSTC_WRAPPER",
|
||||
"SSL_CERT_DIR",
|
||||
"SSL_CERT_FILE",
|
||||
"UV_DEFAULT_INDEX",
|
||||
@@ -648,6 +693,7 @@ describe("sanitizeHostExecEnvWithDiagnostics", () => {
|
||||
expect(result.env.CLASSPATH).toBeUndefined();
|
||||
expect(result.env.CXX).toBeUndefined();
|
||||
expect(result.env.CMAKE_C_COMPILER).toBeUndefined();
|
||||
expect(result.env.CARGO_BUILD_RUSTC_WRAPPER).toBeUndefined();
|
||||
expect(result.env.CARGO_REGISTRIES_CRATES_IO_INDEX).toBeUndefined();
|
||||
expect(result.env.PIP_INDEX_URL).toBeUndefined();
|
||||
expect(result.env.PIP_PYPI_URL).toBeUndefined();
|
||||
@@ -684,9 +730,13 @@ describe("sanitizeHostExecEnvWithDiagnostics", () => {
|
||||
expect(result.env.GOPRIVATE).toBeUndefined();
|
||||
expect(result.env.GOENV).toBeUndefined();
|
||||
expect(result.env.GOPATH).toBeUndefined();
|
||||
expect(result.env.HGRCPATH).toBeUndefined();
|
||||
expect(result.env.HTTPS_PROXY).toBeUndefined();
|
||||
expect(result.env.MAKEFLAGS).toBeUndefined();
|
||||
expect(result.env.MFLAGS).toBeUndefined();
|
||||
expect(result.env.NODE_TLS_REJECT_UNAUTHORIZED).toBeUndefined();
|
||||
expect(result.env.PYTHONUSERBASE).toBeUndefined();
|
||||
expect(result.env.RUSTC_WRAPPER).toBeUndefined();
|
||||
expect(result.env.VIRTUAL_ENV).toBeUndefined();
|
||||
expect(result.env.YARN_RC_FILENAME).toBeUndefined();
|
||||
});
|
||||
@@ -1100,3 +1150,52 @@ describe("compiler override exploit regression", () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("make env exploit regression", () => {
|
||||
it("blocks MAKEFLAGS overrides so make cannot evaluate shell payloads from env", async () => {
|
||||
const makePath = getSystemMakePath();
|
||||
if (!makePath) {
|
||||
return;
|
||||
}
|
||||
|
||||
const tempDir = fs.mkdtempSync(
|
||||
path.join(os.tmpdir(), `openclaw-makeflags-override-${process.pid}-${Date.now()}-`),
|
||||
);
|
||||
const exploitPath = path.join(tempDir, "evil-makeflags.sh");
|
||||
const marker = path.join(os.tmpdir(), `openclaw-makeflags-marker-${process.pid}-${Date.now()}`);
|
||||
|
||||
try {
|
||||
clearMarker(marker);
|
||||
fs.writeFileSync(path.join(tempDir, "Makefile"), "all:\n\t@:\n", "utf8");
|
||||
fs.writeFileSync(exploitPath, `#!/bin/sh\ntouch ${JSON.stringify(marker)}\n`, "utf8");
|
||||
fs.chmodSync(exploitPath, 0o755);
|
||||
|
||||
const exploitValue = `--eval=$(shell ${exploitPath})`;
|
||||
const baseEnv = {
|
||||
PATH: process.env.PATH ?? "/usr/bin:/bin",
|
||||
};
|
||||
|
||||
await runMakeCommand(makePath, tempDir, {
|
||||
...baseEnv,
|
||||
MAKEFLAGS: exploitValue,
|
||||
});
|
||||
|
||||
expect(fs.existsSync(marker)).toBe(true);
|
||||
clearMarker(marker);
|
||||
|
||||
const safeEnv = sanitizeHostExecEnv({
|
||||
baseEnv,
|
||||
overrides: {
|
||||
MAKEFLAGS: exploitValue,
|
||||
},
|
||||
});
|
||||
|
||||
await runMakeCommand(makePath, tempDir, safeEnv);
|
||||
|
||||
expect(fs.existsSync(marker)).toBe(false);
|
||||
} finally {
|
||||
fs.rmSync(tempDir, { recursive: true, force: true });
|
||||
fs.rmSync(marker, { force: true });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user