Skip to content

Commit 3447575

Browse files
committed
Inherit environment variables deemed safe by default
1 parent bfb6ffc commit 3447575

File tree

1 file changed

+54
-7
lines changed

1 file changed

+54
-7
lines changed

src/client/stdio.ts

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { ChildProcess, spawn } from "node:child_process";
2+
import process from "node:process";
23
import { ReadBuffer, serializeMessage } from "../shared/stdio.js";
34
import { JSONRPCMessage } from "../types.js";
45
import { Transport } from "../shared/transport.js";
@@ -17,11 +18,61 @@ 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+
"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+
2576
/**
2677
* Client transport for stdio: this will connect to a server by spawning a process and communicating with it over stdin/stdout.
2778
*
@@ -56,11 +107,7 @@ export class StdioClientTransport implements Transport {
56107
this._serverParams.command,
57108
this._serverParams.args ?? [],
58109
{
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(),
64111
stdio: ["pipe", "pipe", "inherit"],
65112
signal: this._abortController.signal,
66113
},

0 commit comments

Comments
 (0)