Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-42089

CVE-2026-42089: Yeoman Environment RCE Vulnerability

CVE-2026-42089 is a remote code execution flaw in Yeoman Environment that allows arbitrary package installation without user confirmation. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-42089 Overview

CVE-2026-42089 affects Yeoman Environment, a Node.js library that provides an API to discover, create, and run generators. Versions 2.9.0 through 6.0.0 install missing local generator packages from caller-supplied package names without prompting the user. Downstream consumers that forward attacker-controlled project configuration into this code path can trigger arbitrary package installation and code execution during CLI bootstrap. The vulnerable method is installLocalGenerators(), which invokes repository.install() directly. The issue is fixed in version 6.0.0.

Critical Impact

Attacker-controlled package names processed by installLocalGenerators() allow arbitrary npm package installation and code execution in the developer or CI environment running the generator.

Affected Products

  • Yeoman Environment 2.9.0 through versions prior to 6.0.0
  • Downstream CLIs and generators that pass project configuration into installLocalGenerators()
  • Node.js development and continuous integration environments consuming vulnerable Yeoman versions

Discovery Timeline

  • 2026-06-16 - CVE-2026-42089 published to the National Vulnerability Database
  • 2026-06-17 - Last updated in the NVD database

Technical Details for CVE-2026-42089

Vulnerability Analysis

The vulnerability is classified under [CWE-829] Inclusion of Functionality from Untrusted Control Sphere. Yeoman Environment's installLocalGenerators() accepts a packages object keyed by package name and version range, builds npm-style specifiers, and immediately calls repository.install(specs). No user confirmation occurs before installation begins. When a downstream CLI feeds untrusted project configuration into this method, an attacker controls the package specifier executed by npm. npm runs lifecycle scripts such as preinstall and postinstall during installation, providing arbitrary code execution in the user context.

Root Cause

The root cause is missing user interaction on a security-relevant action. The pre-patch implementation treats caller-supplied package data as trusted input and invokes the underlying installer without confirmation, sanitization, or allowlisting.

Attack Vector

Exploitation requires user interaction, typically invoking a downstream CLI that loads a malicious project configuration file (for example, .yo-rc.json) or a poisoned repository. The attack runs locally with the privileges of the developer or build agent. A successful exploit results in code execution during CLI bootstrap before any generator logic completes.

typescript
    * @param  {Object} packages - packages to install key(packageName): value(versionRange).
    * @return  {Boolean} - true if the install succeeded.
    */
-  async installLocalGenerators(packages: Record<string, string | undefined>) {
+  async installLocalGenerators(packages: Record<string, string | undefined>, forceInstall = false) {
     const entries = Object.entries(packages);
     const specs = entries.map(([packageName, version]) => `${packageName}${version ? `@${version}` : ''}`);
+    if (forceInstall) {
+      this.adapter.log.info(`Force install is enabled. Proceeding with installation.`);
+    } else {
+      const { aproveInstall } = await this.adapter.prompt({
+        message: `The following packages need to be installed in the local repository: ${specs.join(', ')}. Do you want to proceed?`,
+        type: 'confirm',
+        name: 'aproveInstall',
+        default: false,
+      });
+      if (!aproveInstall) {
+        throw new Error(`Installation of ${specs.join(', ')} is declined by the user. Install manually and try again.`);
+      }
+    }
+    this.adapter.log.info(`The following packages will be installed in the local repository: ${specs.join(', ')}.`);
     const installResult = await this.repository.install(specs);
     const failToInstall = installResult.find(result => !result.path);
     if (failToInstall) {

Source: GitHub Commit 78d2af7

Detection Methods for CVE-2026-42089

Indicators of Compromise

  • Unexpected npm install activity initiated by a Yeoman-based CLI during project bootstrap
  • Outbound network connections to public or private npm registries from interactive developer sessions
  • New child processes spawned by node executing npm, yarn, or package lifecycle scripts shortly after opening a project
  • Modifications to node_modules or package-lock.json not associated with a user-initiated install command

Detection Strategies

  • Inventory Node.js projects and identify versions of yeoman-environment between 2.9.0 and earlier than 6.0.0
  • Audit .yo-rc.json and similar project configuration files in untrusted repositories for unexpected generator package references
  • Hunt for npm install invocations parented by Yeoman CLI processes in EDR process telemetry

Monitoring Recommendations

  • Alert on package lifecycle script execution (preinstall, install, postinstall) originating from developer workstations or CI runners
  • Monitor outbound traffic from build agents to registries not on an approved allowlist
  • Forward Node.js and npm process telemetry to a centralized logging or SIEM platform for correlation with project clone events

How to Mitigate CVE-2026-42089

Immediate Actions Required

  • Upgrade yeoman-environment to version 6.0.0 or later across all projects and CI pipelines
  • Audit downstream CLIs and generators that invoke installLocalGenerators() for paths that accept untrusted configuration
  • Treat third-party Yeoman generator repositories as untrusted code and review .yo-rc.json before opening them

Patch Information

The fix landed in Yeoman Environment 6.0.0 via Pull Request #753 and commit 78d2af7. The patched installLocalGenerators() now requires an explicit forceInstall flag or interactive user confirmation through adapter.prompt() before invoking repository.install(). Full details are documented in the GitHub Security Advisory GHSA-vv9j-gjw2-j8wp.

Workarounds

  • Pin direct and transitive dependencies on yeoman-environment to 6.0.0 or later using package.jsonoverrides or resolutions
  • Run Yeoman generators inside ephemeral sandboxes or containers without credentials or registry write access
  • Configure npm with ignore-scripts=true in environments that must execute untrusted generators to suppress package lifecycle code
  • Restrict CI runners executing Yeoman generators to a curated registry mirror that only serves vetted packages
bash
# Configuration example
npm install yeoman-environment@^6.0.0
npm config set ignore-scripts true
# Verify installed version
npm ls yeoman-environment

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.