Node.js has several startup flags that shrink what a process can do: --disable-proto, --disallow-code-generation-from-strings, --no-addons, --secure-heap, --frozen-intrinsics, and the permission model. Each blocks one class of behavior, and each can break code that relied on it, so test your service and its dependencies before you enable any of them in production.
The flags at a glance
All behavior below comes from the Node.js CLI documentation.
| Flag | What it does | Main risk of enabling |
|---|---|---|
--disable-proto=delete or throw | Removes the __proto__ property, or makes access throw ERR_PROTO_ACCESS | Old libraries that use __proto__ |
--disallow-code-generation-from-strings | Makes eval and new Function throw. Does not affect node:vm | Template engines and some bundlers |
--no-addons | Disables the node-addons export condition and loading of native addons | Packages with native parts |
--secure-heap=n | Uses an OpenSSL secure heap for some key operations. Size must be a power of two. Not available on Windows | Fixed size, must be large enough |
--frozen-intrinsics | Freezes built-ins like Array and Object. Experimental | The docs say code may break |
--permission | Restricts files, network, child processes and more | Needs explicit grants |
Reading the table
Prototype access. Turning off __proto__ does not remove every prototype pollution path, because other routes to a prototype exist. It removes one common one. Treat it as a layer, not a fix. The full picture is in prototype pollution defenses.
Code from strings. If your code never needs eval, blocking it turns an injection that reaches eval into an exception. The docs state the flag leaves node:vm alone, so code using that module is not covered.
Native addons. Addons run native code with full process privileges. If your service has no native dependencies, --no-addons makes that a verified fact. Run your tests with it first. If something fails, you have found a native package you may not have known about. For background see native addon security risks.
Secure heap. It protects selected OpenSSL allocations from pointer overrun leaks. The docs warn that the heap is fixed size and cannot be resized, so a too small value causes problems. It is off by default.
Frozen intrinsics. The docs mark it Experimental and warn that code may break. It also runs --require and --import modules before freezing, so polyfills can still load. Try it in a test environment, not first in production.
How to roll them out
- Pick one flag at a time, starting with
--disallow-code-generation-from-stringsor--no-addons. - Run the full test suite with the flag on.
- Start a staging instance with it and watch logs for exceptions.
- Set it in the container command or process manager, and check the production start script uses it.
- Record the flags in your runbook so the next engineer knows why they exist.
What flags cannot do
They reduce what common bugs can reach. They are not a sandbox, and the docs call the permission model a seat belt, not a security boundary. See the permission model explained. They also do nothing about a vulnerable dependency, which is why scanning stays necessary.
Safeguard scans dependencies and reports which vulnerable code is reachable. A free scan covers a Node project's lockfile.
Quick check
Does --disable-proto fix prototype pollution?
It removes one route to it, so treat it as a layer. Input validation and safe merge code are still needed.
Is --frozen-intrinsics ready for production?
The Node.js docs mark it Experimental and warn that code may break.
Sources
Last reviewed: 19 October 2026.