Skip to content

docs: Clarification around real world risks and use cases of VM module #40718

Closed
@ghost

Description

📗 API Reference Docs Problem

  • Version: n/a

  • Platform: n/a

  • Subsystem: VM

Affected URL(s):

Description

Apologies if this isn't the appropriate place for this; I wasn't sure if it fell under help versus docs versus somewhere else.

The official docs for the VM module state the following in the first line of it's description.

The vm module is not a security mechanism. Do not use it to run untrusted code.

The last line of the Example: Running an HTTP server within a VM section says:

This may introduce risks when untrusted code is executed, e.g. altering objects in the context in unwanted ways.

Now, I think it's fairly safe to say it's quite clear that blindly running arbitrary code through the vm module (or anything else) is most definitely not secure or safe. Although the second quote is a bit less definitive and things like the contextCodeGeneration option in runInNewContext are almost a bit of a teaser that might lead people to believe in some cases it is okay, but ultimately I digress :)

This issue is two-fold:

First, I'm curious if it's possible to have additional context (no pun intended) about when the vm module is useful in practice to the average developer. I think it's safe to say a lot of people misunderstand it, and in some cases that can have very bad security consequences.

Second, I'm curious if it's possible to elaborate on situations where using the vm module in restricted/well-defined situations it could be safe to run code under certain conditions. The following is a contrived example and one could argue it's not even an example of untrusted code, but I'm hoping it'll at least illustrate the idea.

Say for example you take an expression and parse it into an AST and validate that it only includes certain nodes. For sake of argument, let's say you only accept identifiers, numeric literals, and operators like <, >, ==, and &&. Now take the following example:

const vm = require('vm');

const code = 'apple == 5 && blueberry > 10';
const ctx = Object.create(null);

ctx.apple = 55;
ctx.blueberry = 33;

const myBool = vm.runInNewContext(code, ctx, { contextCodeGeneration: { strings: false } });

Now, you could certainly argue if you're parsing a string into an AST, validating the nodes, etc. that you aren't really running untrusted code at that point, but bear with me. Is this even a valid use case for the module? Is this even safe assuming you can validate the AST and the context you're passing in? Does this make you want to hit your head against your desk? :P

Ultimately, there are obviously other ways to do this, you're already parsing it out, you could just make your own logic to piece it back together without ever running the actual code itself, but this seems like a simple way to actually achieve evaluation of simple JS expressions, among other potential use cases, etc.

I think the vm module is one of the most misunderstood modules out there, because a lot of developers I've talked with either completely misunderstand what it does, how you'd use it, or why you'd even use it, along with the potential for horrible security consequences when used inappropriately. It'd be awesome if the docs could include some more information on the practical side of things and where the module really shines in real world usage. Telling people when not to use something is certainly value added, but also illustrating real world use cases for when you would want to use it can be equally valuable.


  • I would like to work on this issue and
    submit a pull request.

Metadata

Assignees

No one assigned

    Labels

    questionIssues that look for answers.vmIssues and PRs related to the vm subsystem.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions