Skip to content

JavaScript Evaluation Warning

David Ortner edited this page Oct 16, 2025 · 5 revisions

JavaScript evaluation can be enabled in Happy DOM by setting the Browser setting enableJavaScriptEvaluation to "true".

A VM Context is not an isolated environment, and if you run untrusted JavaScript code you are at risk of RCE (Remote Code Execution) attacks. The attacker may escape the VM and execute code at the process level.

We strongly recommend to run Node.js with the flags --disallow-code-generation-from-strings and --frozen-intrinsics when executing untrusted code within Happy DOM. This disables evaluation and freezes intrinsics at the process level, which prevents attackers from escaping the VM. However, there are still no guarantees that an attacker won't find another way to escape the VM that we don't know about yet.

Happy DOM will output a warning in the console if JavaScript evaluation is enabled in an environment without these flags enabled.

How to fix this?

Option 1: Run Node with flags

You can disable code generation from strings (eval) and freeze instrinsics by running Node.js with the flags --disallow-code-generation-from-strings and --frozen-intrinsics. This will disable evaluation and freeze instrinsics (builtins).

eval() and Function will still work within the Happy DOM environment.

Example:

node --disallow-code-generation-from-strings --frozen-intrinsics ./index.js

or by setting an environment variable

export NODE_OPTIONS="--disallow-code-generation-from-strings --frozen-intrinsics"

Option 2: Keep JavaScript Evaluation Disabled

JavaScript evaluation is disabled by default in Happy DOM since v20.

Remove or set the setting enableJavaScriptEvaluation to "false" to disable JavaScript evaluation.

Option 3: Suppress Warning

Only ignore this warning if you trust the code that is executed within Happy DOM. JavaScript can be loaded from external sources or a developer in your project may copy and paste code from the internet containing an attack.

To suppress the warning message you can set the setting suppressInsecureJavaScriptEnvironmentWarning to "true".

How is the attack performed?

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.

Example 1

const { Window } = require('happy-dom');
const window = new Window({ console, settings: { enableJavaScriptEvaluation: true } });

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

Example 2

const { Window } = require('happy-dom');
const window = new Window({ console, settings: { enableJavaScriptEvaluation: true } });

window.document.write(`
  <script>
     function f() { var process = this; console.log('PID:', process.pid) } 
     Object.getPrototypeOf(this.constructor.constructor.prototype).hasOwnProperty = f;
  </script>
`);

process.hasOwnProperty();
Clone this wiki locally