Dynamic Evaluation Risks (eval, new Function)

eval and new Function execute a string as code with full access to their reachable scope — neither provides a meaningful sandbox boundary.

                eval(code) / new Function(...params, body)
              

Purpose

eval() and new Function() both execute a string as JavaScript at runtime. Both are commonly, and incorrectly, believed to offer some degree of isolation for running untrusted code — neither does.

Syntax

eval('console.log("hi")'); // direct eval — runs in the calling scope
const fn = new Function('a', 'b', 'return a + b'); // runs in the global scope only

Behavior notes

  • Direct eval (called literally as eval(...), not through an alias) runs in the calling function’s own scope — full read/write access to its local variables.
  • new Function always runs in the global scope, regardless of where it’s constructed — it cannot see the enclosing function’s local variables at all, but still has full access to every global.
  • Neither restricts access to global objects, built-in constructors, or anything reachable via the prototype chain from any accessible value — there is no partial-trust execution mode inside a single JavaScript realm.
  • Both block a wide range of engine optimizations for the surrounding code, since the engine can no longer statically determine what variables might be read or modified.

Common mistakes

  • Believing a try/catch around an eval call, or a limited-looking local scope, provides any real containment — it doesn’t; the evaluated code can still reach the global object and every built-in.
  • Building a dynamic import() specifier from untrusted input — carries a comparable risk, since the imported module’s code runs with full privileges in its own scope.
  • Reaching for eval/new Function for convenience (dynamic property access, for instance) where bracket notation or another non-evaluating technique already solves the problem.

Runtime notes

Behavior is core ECMAScript, identical everywhere; genuine sandboxing (a separate process, a properly isolated realm with no shared references) is an application-architecture concern, not something these APIs provide on their own.

Taught in these lessons

Updated 2026-09-03