Skip to content

fix: filter invalid env keys before forking utility processes - #333333

Open
LI BINGZHEN (peaceaddpaasion) wants to merge 4 commits into
microsoft:mainfrom
peaceaddpaasion:fix/utility-process-filter-invalid-env-keys
Open

LI BINGZHEN (peaceaddpaasion) wants to merge 4 commits into
microsoft:mainfrom
peaceaddpaasion:fix/utility-process-filter-invalid-env-keys

Conversation

@peaceaddpaasion

Copy link
Copy Markdown

Problem

The utility process extension host inherits the entire environment block via the default generic env processing. On Windows it is possible for the current process environment to contain keys that Node.js considers illegal (for example a variable whose name starts with a digit, often left behind by installers or tampered environments). Because the inherited block is passed on to the forked utility process, the utility process fails to launch with Node \TypeError: Invalid value for env, and the whole extension-host stack silently dies while the front-end UI stays up (built-in commands \command not found, GitHub auth provider never registers, Copilot
o bundle location, logs never initialize).

This makes a trivially-poisoned environment take down all utility processes with no crash surface and no diagnostic trail.

Changes

  • Add \isValidEnvVariableKey()\ in \src/vs/platform/utilityProcess/common/envKey.ts\ - a pure predicate that validates an environment variable key according to Node's name rules (non-empty, starts with a letter or _, remaining chars alphanumeric or _).
  • In \utilityProcess.ts\ \createEnv(), filter the inherited environment with \isValidEnvVariableKey\ before handing it to the child utility process, so an illegal key is dropped instead of crashing the child.
  • Add unit tests in \src/vs/platform/utilityProcess/test/common/envKey.test.ts.

The patch is minimal and purely defensive; legal keys are preserved unchanged.

Why not reuse
emoveDangerousEnvVariables?


emoveDangerousEnvVariables\ targets specific high-risk keys/values inside an already-valid key namespace (e.g. \NODE_OPTIONS). This fix addresses a different layer: the key itself is not a valid identifier, which Node hard-fails on and which no value-stripping can repair. They are complementary, so a separate pure predicate keeps the boundary check explicit.

Testing

  • \isValidEnvVariableKey\ covered for accepted forms, leading-digit rejection, and special-character rejection (digit/symbol/case variants).

Related

Closes nothing; complements the research issue #333316

When a parent process has environment variables whose names Node.js treats
as invalid (e.g. a leading digit or chars outside [A-Za-z0-9_]), forking
a utility process throws 'TypeError: Invalid value for env', breaking the
extension host and leaving commands/auth providers unregistered.

In createEnv() the environment is built by implicitly inheriting the whole
parent process.env (when no explicit env is provided). We strip any key that
does not match a valid name before passing it to utilityProcess.fork().
- Move the Node env-key legality predicate out of the UtilityProcess class
  into src/vs/platform/utilityProcess/common/envKey.ts so it can be shared
  and unit-tested in isolation.
- Add envKey.test.ts covering valid names, leading digits and illegal chars
  (incl. real-world CJK/CLion/IntelliJ/PATH(x86) cases).
- utilityProcess.ts now imports the shared predicate; behavior unchanged
  (filter Node-invalid keys before fork to avoid 'Invalid value for env').
Copilot AI balanced review requested due to automatic review settings August 29, 2026 12:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@peaceaddpaasion

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@peaceaddpaasion

Copy link
Copy Markdown
Author

Joaquín Ruales (@jruales) Robo (@deepak1556) I synced the PR branch with upstream main, which created a new merge commit and dismissed all prior approvals.There are no actual code changes in this update; only the merge from main.Could you kindly re-review and re-approve this PR when you have time? Thanks a lot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants