fix(spawn): sanitize claudecode in shared claude env builders

- strip CLAUDECODE from cliproxy-built Claude environments

- enforce sanitization in ClaudeAdapter buildEnv

- apply same env hardening in shared spawnClaude helper

Refs #588
This commit is contained in:
Tam Nhu Tran
2026-02-20 23:00:47 +07:00
parent 50412dc679
commit d25eda8435
3 changed files with 11 additions and 5 deletions
+6 -1
View File
@@ -20,6 +20,7 @@ import { CLIProxyProvider } from '../types';
import { CompositeTierConfig } from '../../config/unified-config-types';
import { getWebSearchHookEnv } from '../../utils/websearch-manager';
import { getImageAnalysisHookEnv } from '../../utils/hooks/get-image-analysis-hook-env';
import { stripClaudeCodeEnv } from '../../utils/shell-executor';
import { CodexReasoningProxy } from '../codex-reasoning-proxy';
import { ToolSanitizationProxy } from '../tool-sanitization-proxy';
import { HttpsTunnelProxy } from '../https-tunnel-proxy';
@@ -219,13 +220,17 @@ export function buildClaudeEnvironment(config: ProxyChainConfig): Record<string,
Object.entries(effectiveEnvVars).filter(([, v]) => v !== undefined)
) as Record<string, string>;
return {
const mergedEnv = {
...baseEnv,
...effectiveEnvVarsFiltered,
...webSearchEnv,
...imageAnalysisEnv,
CCS_PROFILE_TYPE: 'cliproxy', // Signal to WebSearch hook this is a third-party provider
};
return Object.fromEntries(
Object.entries(stripClaudeCodeEnv(mergedEnv)).filter(([, v]) => v !== undefined)
) as Record<string, string>;
}
/**
+2 -2
View File
@@ -9,7 +9,7 @@ import { spawn, ChildProcess } from 'child_process';
import { TargetAdapter, TargetBinaryInfo, TargetCredentials, TargetType } from './target-adapter';
import { detectClaudeCli, getClaudeCliInfo } from '../utils/claude-detector';
import type { ProfileType } from '../types/profile';
import { escapeShellArg, stripAnthropicEnv } from '../utils/shell-executor';
import { escapeShellArg, stripAnthropicEnv, stripClaudeCodeEnv } from '../utils/shell-executor';
import { ErrorManager } from '../utils/error-manager';
import { getWebSearchHookEnv } from '../utils/websearch-manager';
import { wireChildProcessSignals } from '../utils/signal-forwarder';
@@ -56,7 +56,7 @@ export class ClaudeAdapter implements TargetAdapter {
if (creds.apiKey) env['ANTHROPIC_AUTH_TOKEN'] = creds.apiKey;
if (creds.model) env['ANTHROPIC_MODEL'] = creds.model;
return env;
return stripClaudeCodeEnv(env);
}
exec(
+3 -2
View File
@@ -6,7 +6,7 @@
*/
import { spawn, ChildProcess, SpawnOptions } from 'child_process';
import { escapeShellArg } from './shell-executor';
import { escapeShellArg, stripClaudeCodeEnv } from './shell-executor';
import { getClaudeCliInfo } from './claude-detector';
import { ErrorManager } from './error-manager';
@@ -46,7 +46,8 @@ export function spawnClaude(options: SpawnClaudeOptions = {}): SpawnClaudeResult
const { args = [], env, cwd, stdio = 'inherit' } = options;
// Merge environment
const mergedEnv = env ? { ...process.env, ...env } : process.env;
const mergedEnvBase = env ? { ...process.env, ...env } : process.env;
const mergedEnv = stripClaudeCodeEnv(mergedEnvBase);
let child: ChildProcess;
if (needsShell) {