@@ -40,6 +40,8 @@ const PROTECTED_ENV_KEYS = Object.freeze({
4040 [ Symbol . iterator ] ( ) { return _PROTECTED_ENV_KEYS [ Symbol . iterator ] ( ) ; } ,
4141} ) ;
4242
43+ const UNSAFE_ENV_KEYS = new Set ( [ '__proto__' , 'constructor' , 'prototype' ] ) ;
44+
4345// --- Structured logging to /var/log/cli-proxy/access.jsonl ---
4446
4547const LOG_DIR = process . env . AWF_CLI_PROXY_LOG_DIR || '/var/log/cli-proxy' ;
@@ -215,7 +217,12 @@ function buildExecEnv(extraEnv) {
215217 if ( extraEnv && typeof extraEnv === 'object' ) {
216218 // Only allow safe string env overrides; never allow overriding keys in PROTECTED_ENV_KEYS.
217219 for ( const [ key , value ] of Object . entries ( extraEnv ) ) {
218- if ( typeof key === 'string' && typeof value === 'string' && ! PROTECTED_ENV_KEYS . has ( key ) ) {
220+ if (
221+ typeof key === 'string'
222+ && typeof value === 'string'
223+ && ! PROTECTED_ENV_KEYS . has ( key )
224+ && ! UNSAFE_ENV_KEYS . has ( key )
225+ ) {
219226 childEnv [ key ] = value ;
220227 }
221228 }
@@ -236,6 +243,19 @@ function buildExecEnv(extraEnv) {
236243 * @returns {Promise<{stdout: string, stderr: string, exitCode: number}> }
237244 */
238245async function runGhCommand ( args , childEnv , stdin ) {
246+ const normalizeExitCode = code => {
247+ if ( typeof code === 'number' && Number . isFinite ( code ) ) {
248+ return code ;
249+ }
250+ if ( typeof code === 'string' ) {
251+ const parsedCode = Number . parseInt ( code , 10 ) ;
252+ if ( ! Number . isNaN ( parsedCode ) ) {
253+ return parsedCode ;
254+ }
255+ }
256+ return 1 ;
257+ } ;
258+
239259 try {
240260 return await new Promise ( ( resolve , reject ) => {
241261 const child = execFile ( 'gh' , args , {
@@ -253,7 +273,7 @@ async function runGhCommand(args, childEnv, stdin) {
253273 resolve ( {
254274 stdout : childStdout || '' ,
255275 stderr : childStderr || '' ,
256- exitCode : err ? ( err . code || 1 ) : 0 ,
276+ exitCode : err ? normalizeExitCode ( err . code ) : 0 ,
257277 } ) ;
258278 } ) ;
259279
0 commit comments