Extensions can pollute process.env inherited by unrelated extensions and child processes
- Dominant language
- TypeScript
- Stars
- 193k
- Forks
- 42.4k
- PR merge metrics
- PR metrics pending
Description
Does this issue occur when all extensions are disabled?: No. The defect is in isolation between extensions running in the same extension host and therefore requires at least one extension.
- VS Code Version: 1.128.0 (fc3def6774c76082adf699d366f31a557ce5573f), x64
- OS Version: Windows 11 10.0.26200 (build 26200)
## Problem
An extension can mutate the extension host's global `process.env`. The mutation is then visible to unrelated extensions and is inherited by child processes that those extensions launch.
A faulty extension currently sets `DEBUG=release`. A separate Java/Gradle extension launches its language server from the same affected environment. The value then propagates through Gradle to a Spring Boot application, where Spring Boot interprets `DEBUG` as its global debug switch and emits framework DEBUG logs plus the full conditions evaluation report.
The originating extension defect is tracked separately at openai/codex#13694. This report is about the VS Code platform boundary that permits one extension's accidental global environment mutation to affect unrelated extensions and their tools.
## Generic reproduction
Use two minimal desktop extensions assigned to the same local extension host.
Extension A activation:
```js
exports.activate = function () {
process.env.VSCODE_EXTENSION_ISOLATION_REPRO = 'from-extension-a';
};
```
Extension B activation:
```js
const cp = require('child_process');
exports.activate = function () {
console.log(process.env.VSCODE_EXTENSION_ISOLATION_REPRO);
cp.execFile(
process.env.ComSpec,
['/d', '/s', '/c', 'echo %VSCODE_EXTENSION_ISOLATION_REPRO%'],
(_, stdout) => console.log(stdout.trim())
);
};
```
Steps:
1. Start an Extension Development Host with both extensions.
2. Activate extension A.
3. Activate extension B.
4. Observe extension B reading `from-extension-a`.
5. Observe the unrelated child process also inheriting `from-extension-a`.
## Actual result
A global environment mutation made by extension A is observable by extension B and inherited by extension B's child process. In the real-world case the confirmed chain is:
```text
extension A -> shared extension host process.env
-> extension B child process
-> Gradle daemon
-> Spring Boot application
```
Closing terminals, restarting VS Code, and rebooting Windows do not solve the problem because the extension repeats the mutation when the new extension host starts.
## Expected result
An extension should not be able to unintentionally alter the environment observed by unrelated extensions and their child processes. Possible platform-level approaches include isolating extension environments, restoring the host environment after extension callbacks, or providing a child-process environment boundary that does not inherit arbitrary mutations from unrelated extensions.
At minimum, the shared global behavior and the requirement for extension authors to avoid mutating `process.env` should be explicitly documented.
## Confirmed A/B evidence
With the same downstream application and configuration:
- inherited `DEBUG=release`: framework DEBUG lines and the Spring Boot conditions evaluation report appear
- removing `DEBUG` immediately before the final child process: the application starts with zero DEBUG lines and no conditions evaluation report
This demonstrates cross-extension environment propagation rather than an application logging configuration change.
Related originating-extension defect: https://github.com/openai/codex/issues/13694
Contributor guide
Assessment
This issue has not been assessed yet.