1
1
import { ChildProcess , spawn } from "node:child_process" ;
2
+ import process from "node:process" ;
2
3
import { ReadBuffer , serializeMessage } from "../shared/stdio.js" ;
3
4
import { JSONRPCMessage } from "../types.js" ;
4
5
import { Transport } from "../shared/transport.js" ;
@@ -17,11 +18,61 @@ export type StdioServerParameters = {
17
18
/**
18
19
* The environment to use when spawning the process.
19
20
*
20
- * The environment is NOT inherited from the parent process by default .
21
+ * If not specified, the result of getDefaultEnvironment() will be used .
21
22
*/
22
- env ?: object ;
23
+ env ?: Record < string , string > ;
23
24
} ;
24
25
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
+ "ALLUSERSPROFILE" ,
33
+ "APPDATA" ,
34
+ "HOMEDRIVE" ,
35
+ "HOMEPATH" ,
36
+ "LOCALAPPDATA" ,
37
+ "NUMBER_OF_PROCESSORS" ,
38
+ "OS" ,
39
+ "PATH" ,
40
+ "PATHEXT" ,
41
+ "PROCESSOR_ARCHITECTURE" ,
42
+ "SYSTEMDRIVE" ,
43
+ "SYSTEMROOT" ,
44
+ "TEMP" ,
45
+ "TMP" ,
46
+ "USERNAME" ,
47
+ "USERPROFILE" ,
48
+ "WINDIR" ,
49
+ ]
50
+ : /* list inspired by the default env inheritance of sudo */
51
+ [ "HOME" , "LOGNAME" , "PATH" , "SHELL" , "TERM" , "USER" ] ;
52
+
53
+ /**
54
+ * Returns a default environment object including only environment variables deemed safe to inherit.
55
+ */
56
+ export function getDefaultEnvironment ( ) : Record < string , string > {
57
+ const env : Record < string , string > = { } ;
58
+
59
+ for ( const key of DEFAULT_INHERITED_ENV_VARS ) {
60
+ const value = process . env [ key ] ;
61
+ if ( value === undefined ) {
62
+ continue ;
63
+ }
64
+
65
+ if ( value . startsWith ( "()" ) ) {
66
+ // Skip functions, which are a security risk.
67
+ continue ;
68
+ }
69
+
70
+ env [ key ] = value ;
71
+ }
72
+
73
+ return env ;
74
+ }
75
+
25
76
/**
26
77
* Client transport for stdio: this will connect to a server by spawning a process and communicating with it over stdin/stdout.
27
78
*
@@ -56,11 +107,7 @@ export class StdioClientTransport implements Transport {
56
107
this . _serverParams . command ,
57
108
this . _serverParams . args ?? [ ] ,
58
109
{
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 } ,
110
+ env : this . _serverParams . env ?? getDefaultEnvironment ( ) ,
64
111
stdio : [ "pipe" , "pipe" , "inherit" ] ,
65
112
signal : this . _abortController . signal ,
66
113
} ,
0 commit comments