help
help copied to clipboard
chroot jail for node_modules
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.
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.
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 thanks can you explain how that works at the bottom of your post? I dont quite follow.
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 thats an interesting approach, i think i understand it.
Does the NODE_PRESERVE_SYMLINKS env var exist already? is it recognized?
Yes, https://nodejs.org/api/cli.html#cli_node_preserve_symlinks_1
I think you can also add the --preserve-symlinks-main flag to avoid having to create the main file outside of the symlinked folder.
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)
Should this be moved to nodejs/help? It seems like a question more than anything else. Label added.
Moving...
@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 - is there anything outstanding here?
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.
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.
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.