Skip to content

Conversation

@renovate
Copy link
Contributor

@renovate renovate bot commented Oct 11, 2025

This PR contains the following updates:

Package Change Age Confidence
happy-dom 17.4.020.0.0 age confidence

GitHub Vulnerability Alerts

CVE-2025-61927

Escape of VM Context gives access to process level functionality

Summary

Happy DOM v19 and lower contains a security vulnerability that puts the owner system at the risk of RCE (Remote Code Execution) attacks.

A Node.js VM Context is not an isolated environment, and if the user runs untrusted JavaScript code within the Happy DOM VM Context, it may escape the VM and get access to process level functionality.

It seems like what the attacker can get control over depends on if the process is using ESM or CommonJS. With CommonJS the attacker can get hold of the require() function to import modules.

Happy DOM has JavaScript evaluation enabled by default. This may not be obvious to the consumer of Happy DOM and can potentially put the user at risk if untrusted code is executed within the environment.

Reproduce

CommonJS (Possible to get hold of require)

const { Window } = require('happy-dom');
const window = new Window({ console });

window.document.write(`
  <script>
     const process = this.constructor.constructor('return process')();
     const require = process.mainModule.require;
  
     console.log('Files:', require('fs').readdirSync('.').slice(0,3));
  </script>
`);

ESM (Not possible to get hold of import or require)

const { Window } = require('happy-dom');
const window = new Window({ console });

window.document.write(`
  <script>
     const process = this.constructor.constructor('return process')();
  
     console.log('PID:', process.pid);
  </script>
`);

Potential Impact

Server-Side Rendering (SSR)

const { Window } = require('happy-dom');
const window = new Window();
window.document.innerHTML = userControlledHTML;

Testing Frameworks

Any test suite using Happy-DOM with untrusted content may be at risk

Attack Scenarios

  1. Data Exfiltration: Access to environment variables, configuration files, secrets
  2. Lateral Movement: Network access for connecting to internal systems. Happy DOM already gives access to the network by fetch, but has protections in place (such as CORS and header validation etc.).
  3. Code Execution: Child process access for running arbitrary commands
  4. Persistence: File system access

Recommended Immediate Actions

  1. Update Happy DOM to v20 or above
    • This version has JavaScript evaluation disabled by default
    • This version will output a warning if JavaScript is enabled in an insecure environment
  2. Run Node.js with the "--disallow-code-generation-from-strings" if you need JavaScript evaluation enabled
    • This makes sure that evaluation can't be used at process level to escape the VM
    • eval() and Function() can still be used within the Happy DOM VM without any known security risk
    • Happy DOM v20 and above will output a warning if this flag is not in use
  3. If you can't update Happy DOM right now, it's recommended to disable JavaScript evaluation, unless you completely trust the content within the environment

Technical Root Cause

All classes and functions inherit from Function. By walking the constructor chain it's possible to get hold of Function at process level. As Function can evaluate code from strings, it's possible to execute code at process level.

Running Node with the "--disallow-code-generation-from-strings" flag protects against this.


  • If you want to rebase/retry this PR, check this box

This PR has been generated on behalf of Nordcom AB by Renovate Bot.

@renovate renovate bot added the Dependency label Oct 11, 2025
@renovate renovate bot enabled auto-merge (rebase) October 11, 2025 01:37
@vercel
Copy link

vercel bot commented Oct 11, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
commerce-demo Error Error Dec 31, 2025 5:19pm
commerce-landing-demo Error Error Dec 31, 2025 5:19pm

@github-actions
Copy link

github-actions bot commented Oct 11, 2025

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 16.77% 2864 / 17075
🔵 Statements 16.77% 2864 / 17075
🔵 Functions 51.19% 279 / 545
🔵 Branches 66.11% 677 / 1024
File CoverageNo changed files found.
Generated in workflow #10779 for commit 82b05ec by the Vitest Coverage Report Action

@codecov
Copy link

codecov bot commented Oct 11, 2025

❌ 2 Tests Failed:

Tests completed Failed Passed Skipped
182 2 180 20
View the top 2 failed test(s) by shortest run time
apps/admin/src/utils/auth.adapter.test.ts > src/utils/auth.adapter.test.ts
Stack Traces | 0s run time
Error: querySrv ENOTFOUND _mongodb._tcp.dummy-string
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { errno: undefined, code: 'ENOTFOUND', syscall: 'querySrv', hostname: '_mongodb._tcp.dummy-string' }
apps/storefront/src/components/products/quantity-selector.test.tsx > components > QuantitySelector > updates the quantity when input value changes
Stack Traces | 1.04s run time
AssertionError: expected "spy" to be called with arguments: [ 5 ]

Number of calls: 0


Ignored nodes: comments, script, style
<html>
  <head />
  <body>
    <div>
      <section
        class="flex min-h-fit w-full overflow-hidden rounded-lg border-2 border-solid border-white bg-white p-0 leading-none opacity-50 drop-shadow transition-colors *:appearance-none *:text-center *:text-lg *:leading-none *:transition-colors"
      >
        <button
          aria-disabled="true"
          aria-label="decrease"
          class="transition-color duration-150 pointer-events-none cursor-not-allowed shadow-none aspect-[3/4] h-full select-none appearance-none rounded-none bg-transparent p-2 font-bold text-current"
          data-nosnippet="true"
          data-quantity-decrease="true"
          data-testid="quantity-decrease"
          disabled=""
          draggable="false"
          title="decrease"
          type="button"
        >
          –
        </button>
        <input
          aria-disabled="true"
          aria-label="quantity"
          class="rounded-lg pointer-events-none cursor-not-allowed h-full w-full grow appearance-none border-none bg-transparent text-sm font-bold outline-none focus:outline-none focus:ring-0"
          data-nosnippet="true"
          data-quantity-input="true"
          data-testid="quantity-input"
          disabled=""
          draggable="false"
          max="199999"
          min="1"
          pattern="[0-9]"
          placeholder="quantity"
          step="1"
          title="quantity"
          type="number"
          value="0"
        />
        <button
          aria-disabled="true"
          aria-label="increase"
          class="transition-color duration-150 pointer-events-none cursor-not-allowed shadow-none aspect-[3/4] h-full select-none appearance-none rounded-none bg-transparent p-2 font-bold text-current"
          data-nosnippet="true"
          data-quantity-increase="true"
          data-testid="quantity-increase"
          disabled=""
          draggable="false"
          title="increase"
          type="button"
        >
          +
        </button>
      </section>
    </div>
  </body>
</html>
 ❯ .../components/products/quantity-selector.test.tsx:27:36
 ❯ runWithExpensiveErrorDiagnosticsDisabled ../../node_modules/.pnpm/@testing-library+dom@10.1.0/node_modules/@.../dom/dist/config.js:47:12
 ❯ checkCallback ../../node_modules/.pnpm/@testing-library+dom@10.1.0/node_modules/@.../dom/dist/wait-for.js:124:77
 ❯ checkRealTimersCallback ../../node_modules/.pnpm/@testing-library+dom@10.1.0/node_modules/@.../dom/dist/wait-for.js:118:16
 ❯ Timeout.<anonymous> ../../node_modules/.pnpm/happy-dom@17.4..../src/window/BrowserWindow.ts:1431:16

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@renovate renovate bot force-pushed the deps/bot-npm-happy-dom-vulnerability branch from becae77 to d3eb268 Compare October 16, 2025 00:58
@renovate renovate bot force-pushed the deps/bot-npm-happy-dom-vulnerability branch from d3eb268 to 6562c93 Compare October 21, 2025 10:59
@renovate renovate bot force-pushed the deps/bot-npm-happy-dom-vulnerability branch from 6562c93 to 9feb7fd Compare November 10, 2025 20:06
@renovate renovate bot force-pushed the deps/bot-npm-happy-dom-vulnerability branch from 9feb7fd to 2ad284a Compare November 18, 2025 12:47
@renovate renovate bot force-pushed the deps/bot-npm-happy-dom-vulnerability branch from 2ad284a to 918ac8f Compare November 27, 2025 10:11
@renovate renovate bot force-pushed the deps/bot-npm-happy-dom-vulnerability branch from 918ac8f to bf40cf9 Compare December 3, 2025 18:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant