Skip to the solution
EasyPhone Screen7 min read

What are the main security risks of using the 'eval()' function in Node.js?

811 views

The problem

Question presented to candidate: "A code review flags eval(userInput) inside an API handler. Walk through exactly what an attacker could do with that, concretely, not just 'it's dangerous.'"

What a strong answer should cover:

  • eval(str) executes str as arbitrary JavaScript, with full access to the surrounding scope β€” not a sandboxed, restricted evaluation of "just an expression." Anything the calling code could do, the evaluated string can also do.
  • πŸ“Œ A concrete, demonstrated consequence, not a hypothetical one: code passing user input to eval() can be made to read variables in the enclosing closure it was never given access to, call require() to load arbitrary modules (including child_process to run OS commands), and even reassign an outer-scope variable β€” genuinely mutating state outside the function's own scope.
  • This is a form of code injection, the same class of vulnerability as SQL injection, just for the JavaScript language itself rather than a query language β€” untrusted input is being interpreted as code rather than treated purely as data.
  • eval() also defeats most static analysis and minification/bundling optimizations β€” a bundler cannot safely tree-shake or rename anything that might be referenced by a dynamically-evaluated string, which is a real, separate cost even in a codebase with no malicious input at all.
  • The standard, correct alternatives depend on the actual need: JSON.parse for parsing data (never eval for this β€” a classic, real historical mistake before JSON.parse was standard); a proper expression parser/sandboxed evaluation library for genuinely needing to evaluate a restricted user-supplied formula; or simply restructuring the code so no string ever needs to become executable code at all.
  • new Function(str) and vm.runInNewContext are related, sometimes-confused mechanisms: new Function still executes arbitrary code (with a different, more limited scope than eval, but still not safe for untrusted input); Node's built-in vm module offers a genuine, deliberately-scoped sandbox, though it is not a complete, airtight security boundary either and needs careful, correct configuration.

Clarifying questions expected:

  • "Is the input ever attacker-controlled, even indirectly, or is it fully trusted internal data?" β€” the entire risk hinges on this.
  • "Is the actual need 'evaluate a small user-supplied math expression' or something broader?" β€” decides whether a restricted expression parser is a sufficient, safer substitute.

Code / implementation expected: Yes β€” actually demonstrating eval reading and mutating outer scope, and calling require(), is the concrete, convincing version of this answer, not an abstract warning.

  • security
  • best-practices
  • eval

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

7 min read Β· 9 sections

Read the code

JavaScriptA real, run demonstration of eval() reading, mutating, and using require() from inside an evaluated string
let secret = "super-secret-value";

function processUserInput(expr) {
  return eval(expr); // NEVER do this with untrusted input β€” demonstration only
}

console.log(processUserInput("2+2"));
// 4 β€” the "intended" calculator use

console.log(processUserInput("secret"));
// super-secret-value β€” read a variable it was never given access to

console.log(processUserInput('require("os").platform()'));
// win32 β€” loaded and called an arbitrary module

processUserInput('secret = "OVERWRITTEN BY EVAL"');
console.log(secret);
// OVERWRITTEN BY EVAL β€” mutated the outer scope directly

// The correct alternative for data:
const data = JSON.parse('{"x": 1}'); // never eval() for this

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 11 of 152 in Node.js

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All Node.js questions
Up nextEasy

What is the difference between string concatenation and path.join/path.resolve?

Continue