Skip to content

src: disable default eval (notable-change)#62436

Open
PR3C14D0 wants to merge 4 commits intonodejs:mainfrom
PR3C14D0:feat/disable-default-eval
Open

src: disable default eval (notable-change)#62436
PR3C14D0 wants to merge 4 commits intonodejs:mainfrom
PR3C14D0:feat/disable-default-eval

Conversation

@PR3C14D0
Copy link

@PR3C14D0 PR3C14D0 commented Mar 25, 2026

This pull request introduces a new CLI flag to Node.js that allows enabling the use of eval() and new Function(), which are now disabled by default for improved security. The implementation ensures that code generation from strings is blocked unless explicitly allowed via the new flag, and updates both the runtime and documentation accordingly. A new test verifies the correct behavior of the flag.

This PR Fixes #62434

Security and Runtime Behavior:

  • By default, eval() and new Function() are now disabled to prevent arbitrary code execution vulnerabilities. They can be re-enabled with the new --enable-eval CLI flag. [1] [2] [3]
  • When creating new contexts (including snapshots), code generation from strings is explicitly disallowed unless the --enable-eval flag is set.

CLI and Documentation:

  • Added the --enable-eval CLI flag, documented its usage, and explained its security implications in doc/api/cli.md. [1] [2]

Testing:

  • Added a new test (test/parallel/test-enable-eval-flag.js) to verify that eval() and new Function() are blocked by default, allowed when the flag is set, and behave as expected in subprocesses and the current process.

(Summary created by Copilot)

This introduces a new boolean option `enable_eval` to PerIsolateOptions and registers the `--enable-eval` flag. This flag will be used to explicitly opt-in to dynamic code generation.
Modify context initialization to set kAllowCodeGenerationFromStrings to false by default in both snapshot and runtime. Update ModifyCodeGenerationFromStrings callback to strictly respect the embedder data, effectively disabling eval() and new Function() unless the --enable-eval flag is provided.
@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/config

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. labels Mar 25, 2026
@PR3C14D0 PR3C14D0 changed the title feat: disable default eval (notable-change) src: disable default eval (notable-change) Mar 25, 2026
Copy link
Member

@addaleax addaleax left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would have been reasonable 15 years ago, not now. There's nothing that would justify the ecosystem breakage that comes with a change like this.

As others pointed out in the related ticket, there's a flag that already exists; that it's opt-in is probably not the ideal security state, but it seems like the best we can achieve at this point.

@PR3C14D0
Copy link
Author

This would have been reasonable 15 years ago, not now. There's nothing that would justify the ecosystem breakage that comes with a change like this.

As others pointed out in the related ticket, there's a flag that already exists; that it's opt-in is probably not the ideal security state, but it seems like the best we can achieve at this point.

Same message I posted at the issue (copy-paste :p):

My proposal is simple, disabling eval by default, and if you want it, you enable it.

About the thing of breaking some repositories, I also propose creating a global way to enabling eval if necessary, such as enabling on .npmrc. We should care for the inexpert developers, or people that don't expect being infected like that

Copy link
Member

@ljharb ljharb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JS spec requires eval be available by default. This change can never and should never happen.

@ljharb ljharb added the semver-major PRs that contain breaking changes and should be released in the next major version. label Mar 26, 2026
@PR3C14D0
Copy link
Author

PR3C14D0 commented Mar 26, 2026

The JS spec requires eval be available by default. This change can never and should never happen.

so, what do you propose for protecting users from executing hidden malicious code? This is a content security policy, it can be extended to be used on specific use-cases, but not always enabled. V8 needs to have eval for comply with the specifications, but this doesn't mean killing eval

@ljharb
Copy link
Member

ljharb commented Mar 26, 2026

There can never exist a mechanism that truly protects against this, because of a design choice made 30 years ago.

I don't object to a flag in general, but a flag virtually nobody will be able to enable (because legitimate usage of eval is quite prevalent in the ecosystem, albeit deeply in the dep graph) is not worth adding.

@PR3C14D0
Copy link
Author

There can never exist a mechanism that truly protects against this, because of a design choice made 30 years ago.

I don't object to a flag in general, but a flag virtually nobody will be able to enable (because legitimate usage of eval is quite prevalent in the ecosystem, albeit deeply in the dep graph) is not worth adding.

and why not forcing that if you need the eval after, lets say, 26.1.xx, force them to enable eval if they want it?

@targos
Copy link
Member

targos commented Mar 26, 2026

The flag already exists: https://nodejs.org/docs/latest/api/cli.html#disallow-code-generation-from-strings

@PR3C14D0
Copy link
Author

I have a new idea, idk if this new idea seems good to you, if you download a repository that has preinstall or postinstall scripts, the implementation of a mechanism that notifies you before running it...

Something like The project has a preinstall script, do you want to run it? (y/N)

@PR3C14D0
Copy link
Author

PR3C14D0 commented Mar 26, 2026

Or maybe, instead of disabling eval by default, doing like Deno?
If you are running eval(), disabling access to the filesystem, networking, environment variables and launching workers and enabling those accesses with allow flags?? What do you think @ljharb @targos @addaleax

@ljharb
Copy link
Member

ljharb commented Mar 26, 2026

To not be breaking, eval must run in the same realm as all other JS code - which eliminates workers or other "safe" contexts.

As for pre/post install scripts, that's not something node is capable of addressing - that'd be an npm thing. Additionally, eval isn't a particularly significant attack vector in install scripts - you can just write the code directly.

This is probably more productive as a discussion in an issue - not a PR - with a clear problem statement and goals, long before any attempt at providing a solution.

@PR3C14D0
Copy link
Author

To not be breaking, eval must run in the same realm as all other JS code - which eliminates workers or other "safe" contexts.

As for pre/post install scripts, that's not something node is capable of addressing - that'd be an npm thing. Additionally, eval isn't a particularly significant attack vector in install scripts - you can just write the code directly.

This is probably more productive as a discussion in an issue - not a PR - with a clear problem statement and goals, long before any attempt at providing a solution.

I only tried to solve a problem that is affecting lots of people and repositories, it doesn't look good to you all, so I'm proposing changes that I could implement right now in this PR.

Anyways, I propose doing like deno, having permission flags that allow the environment to do some things with eval, or not doing other things

@ljharb
Copy link
Member

ljharb commented Mar 26, 2026

I'm not clear that eval is a problem actually affecting all that many people or repositories. The first step is persuading readers that the problem exists in the first place :-)

@PR3C14D0
Copy link
Author

PR3C14D0 commented Mar 26, 2026

I'm not clear that eval is a problem actually affecting all that many people or repositories. The first step is persuading readers that the problem exists in the first place :-)

In this video made by a Spanish youtuber called Midudev, explains how they tried to hack him through injecting code with one of his friend's account, force-pushing malicious code to the repository.

It is the same malware that affected VSCode Extensions and NPM. I also have a stackblitz project trying to discover the source of the malware, but I got blocked by the malware (LOL).

@PR3C14D0
Copy link
Author

PR3C14D0 commented Mar 26, 2026

Anyways, thanks for the feedback! I agree that demonstrating the problem is important. I'll try to somehow create a PoC of how the malware works and if u want, I'll link it to here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. semver-major PRs that contain breaking changes and should be released in the next major version.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FR] Disable eval() usage by default

5 participants