/flags/javascript/node-disallow-code-generation-from-strings
node --disallow-code-generation-from-strings: block eval and new Function
- tool
- JavaScript
- command
- node
- flag
- --disallow-code-generation-from-strings
- default
- off (eval and new Function are allowed)
- since
- Node.js 9.8.0
node --disallow-code-generation-from-strings app.js makes the built-in features that turn strings into code, eval() and new Function(), throw EvalError: Code generation from strings disallowed for this context instead of running. It is a hardening option: if an attacker manages to pass a string into an eval path, nothing executes. It does not restrict the node:vm module.
Without and with the flag
cat > gen.js <<'EOF'
const vm = require("node:vm");
for (const [label, run] of [
["eval", () => eval("1 + 1")],
["new Function", () => new Function("a", "b", "return a * b")(6, 7)],
["AsyncFunction", () => typeof new (async function () {}).constructor("return 1")],
["GeneratorFunction", () => typeof new (function* () {}).constructor("yield 1")],
["setTimeout(string)", () => typeof setTimeout("1", 0)],
["JSON.parse", () => JSON.parse("[1, 2]").length],
["vm.runInNewContext", () => vm.runInNewContext("2 + 3")],
]) {
try { console.log(label.padEnd(20), "->", run()); }
catch (e) { console.log(label.padEnd(20), "->", e.name + ": " + e.message); }
}
EOF
echo "== default"
node gen.js
echo "== --disallow-code-generation-from-strings"
node --disallow-code-generation-from-strings gen.jsOutput
== default
eval -> 2
new Function -> 42
AsyncFunction -> function
GeneratorFunction -> function
setTimeout(string) -> TypeError: The "callback" argument must be of type function. Received type string ('1')
JSON.parse -> 2
vm.runInNewContext -> 5
== --disallow-code-generation-from-strings
eval -> EvalError: Code generation from strings disallowed for this context
new Function -> EvalError: Code generation from strings disallowed for this context
AsyncFunction -> EvalError: Code generation from strings disallowed for this context
GeneratorFunction -> EvalError: Code generation from strings disallowed for this context
setTimeout(string) -> TypeError: The "callback" argument must be of type function. Received type string ('1')
JSON.parse -> 2
vm.runInNewContext -> 5Only the two code-generation features change. JSON.parse never executes code and keeps working, and vm contexts are explicitly outside the option, as the Node.js documentation says.
What is and is not covered
| Feature | With the flag |
|---|---|
| eval("code") | Throws EvalError |
| new Function("code"), Function("code") | Throws EvalError |
| Async and generator function constructors built from strings | Throw EvalError (same mechanism as Function) |
| setTimeout("code", ms) | Not a code path in Node.js: a string callback is a TypeError with or without the flag |
| JSON.parse | Unaffected, it does not run code |
| node:vm (runInNewContext, Script) | Unaffected, as documented |
| require() and import() of files | Unaffected, modules are compiled by the loader |
When to use it
- Servers that never need eval. Most applications do not call
evalon purpose; the flag turns a code-injection bug into a thrown error. - Finding hidden eval. Run the test suite once with the flag. Each
EvalErrorpoints to a dependency that compiles code at run time, which you may want to know before a security review or before deploying under a browser CSP. - Matching a CSP. Front-end code tested in Node.js behaves like a browser page whose Content Security Policy omits
'unsafe-eval'.
Set it in scripts or for a whole process tree:
node --disallow-code-generation-from-strings server.js
NODE_OPTIONS=--disallow-code-generation-from-strings npm testPitfalls
- It is not a sandbox. Code that is already running can still read files, spawn processes and use
node:vm. Use the Node.js permission model or OS isolation for untrusted code. - Libraries fail late: the
EvalErrorappears only when the code path that compiles a string runs, which can be the first request that uses a template or a validator. Exercise those paths in tests. - The message is generic (
disallowed for this context) and the stack points to the library's internalevalcall; follow the trace up to the first frame in your code to find which dependency it is. The default trace keeps only 10 frames, so raise it with --stack-trace-limit if your code is not visible.
FAQ
Does --disallow-code-generation-from-strings also block the vm module?
No. The Node.js documentation states that the node:vm module is not affected, and the example on this page shows vm.runInNewContext still evaluating code. Treat it as protection against accidental eval, not as a sandbox.
Which libraries break with this flag?
Any library that compiles code from strings at run time: some template engines, schema validators that generate validation functions, older bundles that use eval for source maps, and code that calls new Function to detect the global object. They fail with EvalError when that code path runs.
Is there a browser equivalent?
Yes. A Content Security Policy without 'unsafe-eval' in script-src blocks eval and new Function in browsers, and the error is also an EvalError.