fix(security): block build-tool and glibc env injection vectors in host exec sandbox#49702
Conversation
Greptile SummaryThis PR extends the host exec environment variable blocklist with seven new injection vectors (follow-up to #49025): six JVM/glibc/dotnet direct-injection vars added to Changes:
Confidence Score: 4/5
|
🔒 Aisle Security AnalysisWe found 1 potential security issue(s) in this PR:
1. 🟠 Blocked override env vars (e.g., GRADLE_USER_HOME) not enforced in gateway exec path
Description
As a result, an untrusted caller that can supply Impact examples:
Vulnerable code (override blocklist is ignored): // src/agents/bash-tools.exec-runtime.ts
export function validateHostEnv(env: Record<string, string>): void {
for (const key of Object.keys(env)) {
const upperKey = key.toUpperCase();
if (isDangerousHostEnvVarName(upperKey)) { /* ... */ }
if (upperKey === "PATH") { /* ... */ }
}
}And this validation is the only guard before merging user-provided env overrides for host execution: // src/agents/bash-tools.exec.ts
if (host !== "sandbox" && params.env) {
validateHostEnv(params.env);
}
const mergedEnv = params.env ? { ...baseEnv, ...params.env } : baseEnv;So RecommendationEnforce the override blocklist for host execution paths that accept user-supplied Option A (minimal change): extend import {
isDangerousHostEnvVarName,
isDangerousHostEnvOverrideVarName,
} from "../infra/host-env-security.js";
export function validateHostEnv(env: Record<string, string>): void {
for (const rawKey of Object.keys(env)) {
const key = rawKey.trim();
const upper = key.toUpperCase();
if (isDangerousHostEnvVarName(upper) || isDangerousHostEnvOverrideVarName(upper)) {
throw new Error(`Security Violation: Environment variable '${rawKey}' is forbidden.`);
}
if (upper === "PATH") {
throw new Error("Security Violation: Custom 'PATH' variable is forbidden during host execution.");
}
}
}Option B (preferred): reuse the centralized sanitizer for consistency:
Also add regression tests ensuring Analyzed PR: #49702 at commit Last updated on: 2026-03-18T12:10:48Z |
…vectors in host exec Adds GLIBC_TUNABLES, MAVEN_OPTS, SBT_OPTS, GRADLE_OPTS, ANT_OPTS to blockedKeys, and GRADLE_USER_HOME to blockedOverrideKeys. Source: openclaw#49702
|
CI note: the three persistent failures (contracts, channels, extensions) are pre-existing across all open PRs right now - confirmed on #48805, #48804, #48851 which have the same TS1360 type errors in channelContentConfig.ts. Nothing to do with this PR's JSON/Swift/test changes. All code-relevant checks pass: check (lint/typecheck), both test shards, bun test, startup-memory, secrets, check-docs. |
* main: (230 commits) fix llm-task invalid thinking timeout Build: narrow tsdown unresolved import guard Plugins: sync contract registry image providers Build: fail on unresolved tsdown imports Deps: align pi-agent-core for declaration builds Build: fail on plugin SDK declaration errors Release: add plugin npm publish workflow (openclaw#47678) fix(security): block build-tool and glibc env injection vectors in host exec sandbox (openclaw#49702) test simplify zero-state boundary guards ci enforce boundary guardrails test: enable vmForks for targeted channel test runs test(telegram): fix incomplete sticker-cache mocks in tests Config: align model compat thinking format types Tlon: pin api-beta to current known-good commit Plugin SDK: harden provider auth seams fix(config): add missing qwen-chat-template to thinking format schema Plugin SDK: register provider auth login entrypoint Plugin SDK: split provider auth login seam fix: serialize duplicate channel starts (openclaw#49583) (thanks @sudie-codes) Telegram: fix reply-runtime test typings ...
…st exec sandbox (openclaw#49702) Add GLIBC_TUNABLES, MAVEN_OPTS, SBT_OPTS, GRADLE_OPTS, ANT_OPTS, DOTNET_ADDITIONAL_DEPS to blockedKeys and GRADLE_USER_HOME to blockedOverrideKeys in the host exec security policy. Closes openclaw#22681 (cherry picked from commit 089a43f)
…st exec sandbox (openclaw#49702) Add GLIBC_TUNABLES, MAVEN_OPTS, SBT_OPTS, GRADLE_OPTS, ANT_OPTS, DOTNET_ADDITIONAL_DEPS to blockedKeys and GRADLE_USER_HOME to blockedOverrideKeys in the host exec security policy. Closes openclaw#22681 (cherry picked from commit 089a43f)
…st exec sandbox (openclaw#49702) Add GLIBC_TUNABLES, MAVEN_OPTS, SBT_OPTS, GRADLE_OPTS, ANT_OPTS, DOTNET_ADDITIONAL_DEPS to blockedKeys and GRADLE_USER_HOME to blockedOverrideKeys in the host exec security policy. Closes openclaw#22681
…st exec sandbox (openclaw#49702) Add GLIBC_TUNABLES, MAVEN_OPTS, SBT_OPTS, GRADLE_OPTS, ANT_OPTS, DOTNET_ADDITIONAL_DEPS to blockedKeys and GRADLE_USER_HOME to blockedOverrideKeys in the host exec security policy. Closes openclaw#22681
…st exec sandbox (openclaw#49702) Add GLIBC_TUNABLES, MAVEN_OPTS, SBT_OPTS, GRADLE_OPTS, ANT_OPTS, DOTNET_ADDITIONAL_DEPS to blockedKeys and GRADLE_USER_HOME to blockedOverrideKeys in the host exec security policy. Closes openclaw#22681
…st exec sandbox (openclaw#49702) Add GLIBC_TUNABLES, MAVEN_OPTS, SBT_OPTS, GRADLE_OPTS, ANT_OPTS, DOTNET_ADDITIONAL_DEPS to blockedKeys and GRADLE_USER_HOME to blockedOverrideKeys in the host exec security policy. Closes openclaw#22681
…st exec sandbox (openclaw#49702) Add GLIBC_TUNABLES, MAVEN_OPTS, SBT_OPTS, GRADLE_OPTS, ANT_OPTS, DOTNET_ADDITIONAL_DEPS to blockedKeys and GRADLE_USER_HOME to blockedOverrideKeys in the host exec security policy. Closes openclaw#22681
…st exec sandbox (openclaw#49702) Add GLIBC_TUNABLES, MAVEN_OPTS, SBT_OPTS, GRADLE_OPTS, ANT_OPTS, DOTNET_ADDITIONAL_DEPS to blockedKeys and GRADLE_USER_HOME to blockedOverrideKeys in the host exec security policy. Closes openclaw#22681
…st exec sandbox (openclaw#49702) Add GLIBC_TUNABLES, MAVEN_OPTS, SBT_OPTS, GRADLE_OPTS, ANT_OPTS, DOTNET_ADDITIONAL_DEPS to blockedKeys and GRADLE_USER_HOME to blockedOverrideKeys in the host exec security policy. Closes openclaw#22681
…st exec sandbox (openclaw#49702) Add GLIBC_TUNABLES, MAVEN_OPTS, SBT_OPTS, GRADLE_OPTS, ANT_OPTS, DOTNET_ADDITIONAL_DEPS to blockedKeys and GRADLE_USER_HOME to blockedOverrideKeys in the host exec security policy. Closes openclaw#22681
…st exec sandbox (openclaw#49702) Add GLIBC_TUNABLES, MAVEN_OPTS, SBT_OPTS, GRADLE_OPTS, ANT_OPTS, DOTNET_ADDITIONAL_DEPS to blockedKeys and GRADLE_USER_HOME to blockedOverrideKeys in the host exec security policy. Closes openclaw#22681 (cherry picked from commit 089a43f)
…st exec sandbox (openclaw#49702) Add GLIBC_TUNABLES, MAVEN_OPTS, SBT_OPTS, GRADLE_OPTS, ANT_OPTS, DOTNET_ADDITIONAL_DEPS to blockedKeys and GRADLE_USER_HOME to blockedOverrideKeys in the host exec security policy. Closes openclaw#22681 (cherry picked from commit 089a43f)
…st exec sandbox (openclaw#49702) Add GLIBC_TUNABLES, MAVEN_OPTS, SBT_OPTS, GRADLE_OPTS, ANT_OPTS, DOTNET_ADDITIONAL_DEPS to blockedKeys and GRADLE_USER_HOME to blockedOverrideKeys in the host exec security policy. Closes openclaw#22681 (cherry picked from commit 089a43f)
Follow-up to #49025. Extends the host exec env var blocklist with seven more injection vectors verified against official documentation.
Changes
src/infra/host-env-security-policy.json:blockedKeys: addGLIBC_TUNABLES,MAVEN_OPTS,SBT_OPTS,GRADLE_OPTS,ANT_OPTS,DOTNET_ADDITIONAL_DEPSblockedOverrideKeys: addGRADLE_USER_HOME(path redirect, not direct injection - follows HOME/OPENSSL_CONF pattern)apps/macos/Sources/OpenClaw/HostEnvSecurityPolicy.generated.swift: regeneratedsrc/infra/host-env-security.test.ts: assertions for all new entries with case-insensitive coverageWhy these vars?
GLIBC_TUNABLESLD_prefix.MAVEN_OPTS-javaagent:.SBT_OPTSGRADLE_OPTSANT_OPTSGRADLE_USER_HOMEinit.d/*.gradlewith full Groovy/OS access.DOTNET_ADDITIONAL_DEPSWhy GRADLE_USER_HOME is blockedOverrideKeys, not blockedKeys
GRADLE_USER_HOME is a path-redirect variable, not a direct code injection flag. It follows the same pattern as
HOME,CURL_HOME, andOPENSSL_CONFinblockedOverrideKeys:The JVM-opts vars (MAVEN_OPTS, SBT_OPTS, GRADLE_OPTS, ANT_OPTS) accept arbitrary JVM flags including
-javaagent:, making even inherited values a potential injection vector. They follow the NODE_OPTIONS/JAVA_TOOL_OPTIONS pattern in blockedKeys.Not included
GOFLAGS/RUSTFLAGS/CARGO_HOME: build flag injection but lower severity. Tracked for a follow-up.GEM_HOME/GEM_PATH:RUBYLIBandRUBYOPTalready blocked.JAVA_OPTS: generic JVM opts convention, read by some tools (Tomcat, Kafka) but not by the four build tool launchers. Could add in a follow-up if needed.Regression risk
MAVEN_OPTS, SBT_OPTS, GRADLE_OPTS, and ANT_OPTS are legitimately set by Java developers for heap tuning. Agent-spawned build commands will silently lose these flags. Same trade-off already accepted for NODE_OPTIONS and JAVA_TOOL_OPTIONS (#49025).
GRADLE_USER_HOME: NO regression for inherited values (blockedOverrideKeys preserves the user's setting). Only agent-supplied overrides are blocked.
Prior art
Follow-up to #49025 (merged). Both reference #22681.
Test plan
pnpm test -- src/infra/host-env-security.test.tspasses (17 tests)isDangerousHostEnvOverrideVarNametest for GRADLE_USER_HOME