11import { ChildProcess , spawn } from "node:child_process" ;
2+ import process from "node:process" ;
23import { ReadBuffer , serializeMessage } from "../shared/stdio.js" ;
34import { JSONRPCMessage } from "../types.js" ;
45import { Transport } from "../shared/transport.js" ;
@@ -17,11 +18,55 @@ export type StdioServerParameters = {
1718 /**
1819 * The environment to use when spawning the process.
1920 *
20- * The environment is NOT inherited from the parent process by default .
21+ * If not specified, the result of getDefaultEnvironment() will be used .
2122 */
22- env ?: object ;
23+ env ?: Record < string , string > ;
2324} ;
2425
26+ /**
27+ * Environment variables to inherit by default, if an environment is not explicitly given.
28+ */
29+ export const DEFAULT_INHERITED_ENV_VARS =
30+ process . platform === "win32"
31+ ? [
32+ "APPDATA" ,
33+ "HOMEDRIVE" ,
34+ "HOMEPATH" ,
35+ "LOCALAPPDATA" ,
36+ "PATH" ,
37+ "PROCESSOR_ARCHITECTURE" ,
38+ "SYSTEMDRIVE" ,
39+ "SYSTEMROOT" ,
40+ "TEMP" ,
41+ "USERNAME" ,
42+ "USERPROFILE" ,
43+ ]
44+ : /* list inspired by the default env inheritance of sudo */
45+ [ "HOME" , "LOGNAME" , "PATH" , "SHELL" , "TERM" , "USER" ] ;
46+
47+ /**
48+ * Returns a default environment object including only environment variables deemed safe to inherit.
49+ */
50+ export function getDefaultEnvironment ( ) : Record < string , string > {
51+ const env : Record < string , string > = { } ;
52+
53+ for ( const key of DEFAULT_INHERITED_ENV_VARS ) {
54+ const value = process . env [ key ] ;
55+ if ( value === undefined ) {
56+ continue ;
57+ }
58+
59+ if ( value . startsWith ( "()" ) ) {
60+ // Skip functions, which are a security risk.
61+ continue ;
62+ }
63+
64+ env [ key ] = value ;
65+ }
66+
67+ return env ;
68+ }
69+
2570/**
2671 * Client transport for stdio: this will connect to a server by spawning a process and communicating with it over stdin/stdout.
2772 *
@@ -56,11 +101,7 @@ export class StdioClientTransport implements Transport {
56101 this . _serverParams . command ,
57102 this . _serverParams . args ?? [ ] ,
58103 {
59- // The parent process may have sensitive secrets in its env, so don't inherit it automatically.
60- env :
61- this . _serverParams . env === undefined
62- ? { }
63- : { ...this . _serverParams . env } ,
104+ env : this . _serverParams . env ?? getDefaultEnvironment ( ) ,
64105 stdio : [ "pipe" , "pipe" , "inherit" ] ,
65106 signal : this . _abortController . signal ,
66107 } ,
0 commit comments