fix(claude): scrub case-insensitive Windows auth env

This commit is contained in:
Merge Sim
2026-09-01 13:41:55 -07:00
parent af7059994f
commit a9c8cb4e2a
4 changed files with 41 additions and 5 deletions
+10 -3
View File
@@ -13,14 +13,21 @@ export type ClaudeEnvPatch = {
export function applyClaudeEnvPatch(
baseEnv: Record<string, string>,
patch: ClaudeEnvPatch,
options?: { stripAuthEnv?: boolean }
options?: { stripAuthEnv?: boolean; platform?: NodeJS.Platform }
): Record<string, string> {
if (options?.stripAuthEnv) {
for (const key of CLAUDE_AUTH_ENV_VARS) {
delete baseEnv[key]
}
if (isAuthLikeCustomHeaders(baseEnv.ANTHROPIC_CUSTOM_HEADERS)) {
delete baseEnv.ANTHROPIC_CUSTOM_HEADERS
const platform = options.platform ?? process.platform
for (const key of Object.keys(baseEnv)) {
const normalized = platform === 'win32' ? key.toUpperCase() : key
if (
(platform === 'win32' && CLAUDE_AUTH_ENV_VARS.some((authKey) => authKey === normalized)) ||
(normalized === 'ANTHROPIC_CUSTOM_HEADERS' && isAuthLikeCustomHeaders(baseEnv[key]))
) {
delete baseEnv[key]
}
}
}
@@ -1,7 +1,22 @@
import { describe, expect, it } from 'vitest'
import { applyClaudeEnvPatch } from '../claude-accounts/environment'
import { buildClaudeChildProcessEnv } from './claude-child-process-environment'
describe('Claude child process environment', () => {
it('strips case-insensitive auth headers through the shared env patch on Windows', () => {
expect(
applyClaudeEnvPatch(
{
anthropic_api_key: 'inherited-key',
Anthropic_Custom_Headers: 'Authorization: inherited',
SAFE_VALUE: 'preserved'
},
{},
{ stripAuthEnv: true, platform: 'win32' }
)
).toEqual({ SAFE_VALUE: 'preserved' })
})
it('strips case-insensitive inherited auth and session stamps on Windows', () => {
const env = buildClaudeChildProcessEnv(
{
@@ -22,7 +22,14 @@ export function buildClaudeChildProcessEnv(
): Record<string, string> {
const inheritedEnv = options.inheritedEnv ?? process.env
const platform = options.platform ?? process.platform
const env = applyClaudeEnvPatch(cloneProcessEnv(inheritedEnv), {}, { stripAuthEnv: true })
const env = applyClaudeEnvPatch(
cloneProcessEnv(inheritedEnv),
{},
{
stripAuthEnv: true,
platform
}
)
if (platform === 'win32') {
const authKeys = new Set(CLAUDE_AUTH_ENV_VARS.map((key) => key.toUpperCase()))
for (const [key, value] of Object.entries(env)) {
@@ -109,7 +109,14 @@ export function createClaudeStructuredLaunchResolver(
const env = withCliRuntimeOnPath(
command,
{
...applyClaudeEnvPatch(cloneDefinedEnv(process.env), {}, { stripAuthEnv: true }),
...applyClaudeEnvPatch(
cloneDefinedEnv(process.env),
{},
{
stripAuthEnv: true,
platform: process.platform
}
),
...(overlay ? cloneDefinedEnv(overlay) : {})
},
{ platform: process.platform }