Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Security] API access permissions for NPM modules #14

Open
Mickael-van-der-Beek opened this issue Nov 3, 2014 · 4 comments
Open

[Security] API access permissions for NPM modules #14

Mickael-van-der-Beek opened this issue Nov 3, 2014 · 4 comments

Comments

@Mickael-van-der-Beek
Copy link

This feature would involve changes in both the Node.js and NPM projects but I thought that this repository would be an appropriate place to discuss it.

The idea is to basically mock the access permission feature that Android and iOS SDKs have.
Not unlike most OAuth API's, NPM modules could have a "permissions" field in their package.json file that describes a scope of native Node.js modules and type of access (read, write, ...) needed.
e:g:

{
    // usual package.json fields
    // ...
    "permissions": {
        "fs": "rw",     // read + write flag
        "http": "r"         // read flag
    }
}

Naturally, a NPM package would need a scope that consists of all it's dependencies's scopes (recursively calculated at NPM install time) plus it's own.

Installing modules in this mode would be a little different than usual because NPM would have to ask your permission for each top-level module.

Additionally, there could be an option where developers could specify global permissions for every NPM module.
e:g:

{
    // usual package.json fields
    // ...
    "dependencies": {
        "test": "1.0.0"
    },
    "globalPermissions": {
        "filesytem": "r"    // read flag
    }
}

In the following package.json file, if the test module would need a "filesytem": "rw" permission, you would get a conflict.
Conflict resolution could be inspired by Bower's version conflict resolution implementation.

Scopes could include: filesystem, shell, child process, http and tcp (or a network scope that would combine both).

Flags could include: r (read), w (write), o (overriding native methods).

By briefly reading the implementation of the require() method, I saw that a Node.js VM was created with the parent's context.
I'm not a core developer so obviously this is just pure speculation on my part, but maybe this feature could be implemented by limiting the VM's context to the subset of native modules specified in the package.json file ?
Would that be sufficient ?

Some tricky parts:

  • It might be more difficult to limit NPM modules with C/C++ bindings.
  • If you have access to the shell scope you can more or less emulate any other access scope.

You actually have a kind of implied hierarchy to access permissions.

Obviously Node.js wasn't designed with this feature in mind but I think that this could really help NPM and Node.js protect users against malicious modules or hacked developer accounts in an effective way.

It's also a good argument to convince larger companies that hesitated to use Node.js before due to how NPM modules work and the lack of control they have over them (besides versions).

What do you guys think ?

@bnoordhuis
Copy link
Member

maybe this feature could be implemented by limiting the VM's context to the subset of native modules specified in the package.json file ?

This feature has been requested (and discussed) in the past in various guises. It's unlikely that it could be implemented securely or comprehensively and no one was willing to commit to supporting it. OS-level isolation like Linux containers or FreeBSD's Capsicum is really the way to go here.

@Mickael-van-der-Beek
Copy link
Author

Yeah, I thought that it would be really complicated to implement this but I wanted to post the idea anyway in case I was wrong.

Thanks for the quick answer anyway !

@indexzero
Copy link

It's an interesting idea but it seems like a Herculean effort would be needed to implement it since all of these methods would need to be context aware of the entire module chain that invoked them. e.g. I write a module with only "read" permissions for "fs" but use something like fstream which clearly has "read/write" permissions. The fs module needs to know that whole dependency chain for every method invocation because the fstream methods in the context of my module at not ok but in other contexts (such as being a direct or top-level dependency) are ok.

Seems really expensive.

@maySINsCreations
Copy link

Are you still around?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants