-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
[BUG] npm install deletes an existing symlinked node_modules directory #3669
Comments
This behavior is introduced between npm 7.15 and 7.21. The new npm install behavior is to always replace a symlinked node_modules with an actual directory, which breaks the usage of node_modules.nosync and a few existing npm modules that favors this behavior, e.g. nosync-icloud If this breaking change is intended, it should be introduced with a major version upgrade, shouldn’t it? Redirected to here from a long trip,
Commenting in the hope for Google to index this and aid future lost souls to land here. |
This still works in This also breaks when developing using Docker, where code is mounted from the host machine, but |
Confirming a new lower bound of |
Seems like this was added with |
From the commit message it reads,
Sounds like an intentional incompatibility with
Although skippable with In the spirit of semantic versioning it should be at least a major upgrade so the community can be prepared, shouldn't it? |
It works with
|
This is by design, and prevents a class of RCE security exploits. GHSA-gmw6-94gg-2rc2 |
Could there option to keep node_modules as symlink? It basically broke our CI becuse we used node_modules symlinked to shared folder to optimize build - now build that took 2-3 minutes takes about an hour and CI fails on timeout. Reason is it again and again needs to install/copy node_modules in each job. |
Please add an option to disable this! I used node_modules.nosync with iCloud, and the folder has a size of 300 MB. This uses all of my iCloud storage. Using |
Has somebody find a solution or a workaround about this issue? I'm having the same issue and had to downgrade my node version on the server, but it is not the ideal solution. |
@htorohn This is not about node, this is an npm design flaw. You may either downgrade, or switch away, from npm. |
The issue title seems confusing to me, someone please fix: npm seems to not delete the "symlinked |
Asking here since the arborist repo with the original security bulletin GHSA-gmw6-94gg-2rc2 is read-only:
This is meant to defend against malicious scripts installed from/by npm, right? So if npm cannot modify/replace the symbolic link, e.g. because it resides on a read-only mountpoint, shouldn't npm trust the symlink's apparent invulnerability? Instead, for me, npm@8.5.5 on node@v16.14.2 on Ubuntu focal fails with EACCES.
|
This comment was marked as outdated.
This comment was marked as outdated.
Even easier workaround, if you can afford to sacrific one extra layer of directory depth on your shared storage
Thus, npm sees that Edit: A bind mount might be even easier. |
@mk-pmb Please note that the arborist commit is exactly meant to prevent this kind of usage, all workarounds may be patched just to fulfill this opinion. This is a private company's decision, and, while questionable, it doesn't look like it's up for debate. A concise choice is to move away from NPM. |
In my current automated install strategy, it has huge benefits to use a node package manager that I can install from a debian repo as trustworthy as nodesource. (I consider them the same trust level as the nodejs website.) So unless they patch away even the bind mount, … actually, even at that point I'd probably try and just monkey-patch npm. |
@blaumeise20 That's unfortunate, they really should fix it. |
Seems like the fix is to avoid a publicly known security attack by not trying to do this unwise idea in the first place. |
@ljharb That part was explained in the comment above the close. I understand how it might be dangerous if npm, and thus potential scripts, can modify or replace the symlink during install. The remaining mystery is why we need to defend against symlinks that npm cannot modify, due to lack of permission or lack of filesystem capability. |
@mk-pmb npm's inability to modify them might not be permanent, and such a pattern in one system might end up in another system where those guarantees don't exist. |
I see a common pattern: Security defenses that are usually useful, except in edge cases where external safeguards prevent the attack. There should thus be an option to give npm a list of vulnerability IDs (CVEs etc.) that it does not need to defend because the admin has decided it does not apply to their edge case. |
I totally agree! see npm/rfcs#422. That, however, doesn't mean that npm itself should make decisions that are unsafe in nonzero scenarios. |
@ljharb deleting user files without being asked for is by far an "unsafe in nonzero scenarios" decision, no program should do it. The sane option is to refuse working and/or display a visible warning explaining why. |
Sure, eagerly failing loudly would be better also. The outcome is still the same - you wouldn’t be able to do the thing you want, you just would be informed faster. |
Which can be crucial. In my case, removal of the symlink would have caused backup cron jobs to fail if I had not noticed early enough. Worst case scenario would probably be somehow breaking the path to someone's SSH authorization mechanism. I can't imagine what such a setup would look like, but from my tech support experience, I'm sure there are people who will have invented a fragile enough setup. |
Not sure the outcome is still the same. If you delete the symlink but continue the job:
For me the reasonable decision is: the symlink should not be removed, the command should not continue and should exit with non-zero status. It is doing the exact opposite. |
Being a few package maintainer myself, this very decision creates wondrous moments with |
Check dropboxignore out if you just want |
I disagree this actually fixes anything, because the preinstall script can do the same damage in myriad of other ways besides replacing To prevent a preinstall script from doing damage, it would have to be sandboxed, and then that sandbox can prevent it from, among many other things, replacing |
Good point. In before "just disable npm scripts". |
Is there an existing issue for this?
Current Behavior
If a package contains a node_modules that is symlinked then an npm install will issue the message
npm WARN reify Removing non-directory ....
and delete the node_modules directory.
Expected Behavior
A symlinked node_modules directory should be used as is and not recreated - many people symlink node_modules to a local filesystem so that it does not get synced to cloud storage (like Dropbox).
I suspect that the npm code is just checking if any existing file object named node_modules is a directory and does not also check to see if the non-directory file object is actually a symlinked directory.
Steps To Reproduce
cd /tmp
mkdir symlinked
mkdir z
cd z
npm init -y
ln -s /tmp/symlinked node_modules .
npm install lodash
Environment
The text was updated successfully, but these errors were encountered: