src: disable default eval (notable-change)#62436
src: disable default eval (notable-change)#62436PR3C14D0 wants to merge 4 commits intonodejs:mainfrom
Conversation
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.
|
Review requested:
|
addaleax
left a comment
There was a problem hiding this comment.
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 |
ljharb
left a comment
There was a problem hiding this comment.
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 |
|
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? |
|
The flag already exists: https://nodejs.org/docs/latest/api/cli.html#disallow-code-generation-from-strings |
|
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 |
|
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 |
|
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). |
|
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 |
This pull request introduces a new CLI flag to Node.js that allows enabling the use of
eval()andnew 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:
eval()andnew Function()are now disabled to prevent arbitrary code execution vulnerabilities. They can be re-enabled with the new--enable-evalCLI flag. [1] [2] [3]--enable-evalflag is set.CLI and Documentation:
--enable-evalCLI flag, documented its usage, and explained its security implications indoc/api/cli.md. [1] [2]Testing:
test/parallel/test-enable-eval-flag.js) to verify thateval()andnew 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)