help icon indicating copy to clipboard operation
help copied to clipboard

chroot jail for node_modules

Open ORESoftware opened this issue 6 years ago • 15 comments

For testing purposes I am looking to find a way to prevent the node.js executable from searching for node_modules below a certain directory, sort of like a chroot jail but specific to node only.

For example:

node_modules/
project/
    node_modules/
    foo/bar.js

if I run:

cd project && node foo/bar.js

then if it can't find a package in project/node_modules, then it will also look in node_modules (the sibling folder to the project folder).

My feature request is an executable option for node (or env variable) that can prevent node from looking for node_modules outside a certain dir, something like this:

node --modules-jail="." foo/bar.js

or

export NODE_MODULES_JAIL="$HOME/project"
node foo/bar.js

the purpose is for testing packages and to ensure the end user is not "cheating themselves" by accidentally relying on installed packages outside/below the package itself.

ORESoftware avatar Nov 24 '18 20:11 ORESoftware

btw, I tried solving my problem with the chroot command itself - the problem is that global executables can't be used easily, w/o symlinking them into the jail. And in my case, for library development, I would need the user to declare all the executables they would need in the jail and it would be pretty much unusable. If there were a way to use chroot in a manner that files outside the chroot jail could only be executed not read/write, then that would work, but chroot doesn't work like that TMK.

ORESoftware avatar Nov 24 '18 20:11 ORESoftware

Hello @ORESoftware I was thinking a about using NODE_PRESERVE_SYMLINKS=1 to create a lite-symlink-jail. It has only one caveat, the root script can't be in a symlinked dir, so I created a wrapper test_jailed.js:

$HOME/
|
-> node_modules/lodash
|
-> 24633_proj/
            -> test.js == `console.log(require('lodash'))`

/tmp/
|
-> 24633_jail/
            |
            -> jail/ [SYMLINK] to `$HOME/24633_proj/`
            -> test_jailed.js == `require('./jail/test.js')`
~/24633_proj> export NODE_PRESERVE_SYMLINKS=1
~/24633_proj> node test.js
4.17.11
~/24633_proj> cd /tmp/24633_jail/
/tmp/24633_jail> node test_jailed.js
internal/modules/cjs/loader.js:589
    throw err;
    ^

Error: Cannot find module 'lodash'

Notice it doesn't find lodash so in fact it does run test.js

refack avatar Nov 25 '18 19:11 refack

@refack thanks can you explain how that works at the bottom of your post? I dont quite follow.

ORESoftware avatar Nov 25 '18 20:11 ORESoftware

Using your tree structure:

node_modules/
project/
    node_modules/
    foo/bar.js

Assuming you don't have /node_modules/ or /tmp/node_modules/, you can do this:

> mkdir /tmp/project_jail
> cd /tmp/project_jail
> ln -s jail $HOME/project
> echo "require('./jail/foo/bar.js')" > jailer.js
> NODE_PRESERVE_SYMLINKS=1 node jailer.js

With NODE_PRESERVE_SYMLINKS=1 node will not resolve symlink to real paths for everything, but the root script (the one called from the CLI), so you need the jailer.js to live in a "real" directory, and call the entry-point of the symlink-jailed project.

refack avatar Nov 25 '18 22:11 refack

@refack thats an interesting approach, i think i understand it.

ORESoftware avatar Nov 26 '18 10:11 ORESoftware

Does the NODE_PRESERVE_SYMLINKS env var exist already? is it recognized?

ORESoftware avatar Nov 26 '18 10:11 ORESoftware

Yes, https://nodejs.org/api/cli.html#cli_node_preserve_symlinks_1

refack avatar Nov 26 '18 11:11 refack

I think you can also add the --preserve-symlinks-main flag to avoid having to create the main file outside of the symlinked folder.

targos avatar Nov 26 '18 11:11 targos

I thought I remembered it being added, but I was looking for it in the environment variables section, where it isn't (probably due to NODE_OPTIONS covering that use case)

refack avatar Nov 26 '18 11:11 refack

Should this be moved to nodejs/help? It seems like a question more than anything else. Label added.

bnoordhuis avatar Nov 27 '18 14:11 bnoordhuis

Moving...

cjihrig avatar Nov 27 '18 14:11 cjihrig

@bnoordhuis not so much a question as a feature request - I haven't tried the symlinks trick, but that doesn't yet seem to me like an ideal solution tho

ORESoftware avatar Nov 29 '18 04:11 ORESoftware

@ORESoftware - is there anything outstanding here?

gireeshpunathil avatar Jul 22 '19 08:07 gireeshpunathil

Basically the original issue, is for testing NPM packages. Say I have an NPM package located here:

/home/me/.foo/testing_dir

the above dir can access node_modules in these 3 places:

/home/me/.foo/testing_dir/node_modules
/home/me/.foo/node_modules
/home/me/node_modules

I am simply looking to restrict it to only access the first folder, of the 3. One solution I thought of was to temporarily mv the 2nd two dirs:

mv /home/me/.foo/node_modules  /home/me/.foo/node_modules_temp
mv /home/me/node_modules /home/me/node_modules_temp

and then move them back, after I run my process. but that's not ideal. Looking back on this thread, I really don't grok the symlinks solution, although would be happy to use it if I can figure it how it's supposed to work. A docker container might also work, but I am looking for something lighter weight than that.

ORESoftware avatar Jul 22 '19 21:07 ORESoftware

It seems there has been no activity on this issue for a while, and it is being closed in 30 days. If you believe this issue should remain open, please leave a comment. If you need further assistance or have questions, you can also search for similar issues on Stack Overflow. Make sure to look at the README file for the most updated links.

github-actions[bot] avatar May 16 '24 01:05 github-actions[bot]

It seems there has been no activity on this issue for a while, and it is being closed. If you believe this issue should remain open, please leave a comment. If you need further assistance or have questions, you can also search for similar issues on Stack Overflow. Make sure to look at the README file for the most updated links.

github-actions[bot] avatar Jun 15 '24 01:06 github-actions[bot]