refactor: share portable env entry normalization

This commit is contained in:
Peter Steinberger 2026-03-13 21:11:34 +00:00
parent ef15600b3e
commit 84a50acb55
1 changed files with 21 additions and 22 deletions

View File

@ -80,6 +80,23 @@ export function isDangerousHostEnvOverrideVarName(rawKey: string): boolean {
return HOST_DANGEROUS_OVERRIDE_ENV_PREFIXES.some((prefix) => upper.startsWith(prefix));
}
function listNormalizedPortableEnvEntries(
source: Record<string, string | undefined>,
): Array<[string, string]> {
const entries: Array<[string, string]> = [];
for (const [rawKey, value] of Object.entries(source)) {
if (typeof value !== "string") {
continue;
}
const key = normalizeEnvVarKey(rawKey, { portable: true });
if (!key) {
continue;
}
entries.push([key, value]);
}
return entries;
}
export function sanitizeHostExecEnv(params?: {
baseEnv?: Record<string, string | undefined>;
overrides?: Record<string, string> | null;
@ -90,12 +107,8 @@ export function sanitizeHostExecEnv(params?: {
const blockPathOverrides = params?.blockPathOverrides ?? true;
const merged: Record<string, string> = {};
for (const [rawKey, value] of Object.entries(baseEnv)) {
if (typeof value !== "string") {
continue;
}
const key = normalizeEnvVarKey(rawKey, { portable: true });
if (!key || isDangerousHostEnvVarName(key)) {
for (const [key, value] of listNormalizedPortableEnvEntries(baseEnv)) {
if (isDangerousHostEnvVarName(key)) {
continue;
}
merged[key] = value;
@ -105,14 +118,7 @@ export function sanitizeHostExecEnv(params?: {
return markOpenClawExecEnv(merged);
}
for (const [rawKey, value] of Object.entries(overrides)) {
if (typeof value !== "string") {
continue;
}
const key = normalizeEnvVarKey(rawKey, { portable: true });
if (!key) {
continue;
}
for (const [key, value] of listNormalizedPortableEnvEntries(overrides)) {
const upper = key.toUpperCase();
// PATH is part of the security boundary (command resolution + safe-bin checks). Never allow
// request-scoped PATH overrides from agents/gateways.
@ -140,14 +146,7 @@ export function sanitizeSystemRunEnvOverrides(params?: {
return overrides;
}
const filtered: Record<string, string> = {};
for (const [rawKey, value] of Object.entries(overrides)) {
if (typeof value !== "string") {
continue;
}
const key = normalizeEnvVarKey(rawKey, { portable: true });
if (!key) {
continue;
}
for (const [key, value] of listNormalizedPortableEnvEntries(overrides)) {
if (!HOST_SHELL_WRAPPER_ALLOWED_OVERRIDE_ENV_KEYS.has(key.toUpperCase())) {
continue;
}