Remove `npm-shrinkwrap.json`
See original GitHub issueWould you consider removing npm-shrinkwrap.json
from the published ganache-core
package? The use of shrinkwrap in this library makes it painful to use for two main reasons: it dramatically increases the number of dependencies we need, and it makes updates to transitive dependencies (to address bugs or security advisories) difficult.
To quote the npm docs on npm-shrinkwrap.json
:
The recommended use-case for
npm-shrinkwrap.json
is applications deployed through the publishing process on the registry: for example, daemons and command-line tools intended as global installs ordevDependencies
. It’s strongly discouraged for library authors to publish this file, since that would prevent end users from having control over transitive dependency updates.
If there are specific packages that need to be pinned, that can be done via package.json
. But using shrinkwrap is counter-productive, and a constant source of friction. It’s reasonable to use a shrinkwrap for ganache-cli
, but I don’t see the case here.
Possible Solution
Rename npm-shrinkwrap.json
to package-lock.json
, and explicitly pin any dependencies that must be a specific version for this library to function correctly. Use at least a ~
range for others (if not a ^
range), to ensure projects that use this dependency are able to easily update these dependencies when necessary.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:1
- Comments:5 (3 by maintainers)
Top GitHub Comments
There are a couple of reasons we currently ship
npm-shrinkwrap.json
withganache-core
:ganache-core
are high-value targets for malicious npm packages and package authors. Users ofganache-core
are likely to own cryptocurrencies and there is no legal recourse for cryptocurrency theft. It is possible fornpm install
to execute code that installs an application outside of yournode_modules
folder, registers itself to run on startup, and then listen for future clipboard entries – clipboard entries that may contain private keys or mnemonics. By shrinkwrapping our dependency tree we remove the risk of one of our transitive dependencies updating to malicious code.ganache-core
’s dependency tree is large. A “non-breaking” transitive dependency update brokeganache-core
for some users and not for others. And this has happened multiple times. Shipping withoutnpm-shrinkwrap.json
makesganache-core
non-deterministic and makes debugging more difficult.npm-shrinkwrap.json
, from time to time. However, I wouldn’t want to automate this process.npm install
with the--no-shrinkwrap
command to ignore ournpm-shrinkwrap.json
file if you want to (https://blog.npmjs.org/post/145724408060/dealing-with-problematic-dependencies-in-a).Truffle tooling already gets blamed for cryptocurrency loss as it is – due to user negligence or ignorance around blockchain security. I’d like to minimize the chance of a disgruntled Truffle user pursuing some sort of legal action against Truffle.
Another option we’ve discussed internally is to go back to shipping ganache-core as a fully bundled dependency with little to no install-time dependencies (like
ganache-cli
andtruffle
do now).I’ll leave this issue open for now, as I am definitely open to discussion (maintaining the shrinkwrap is a headache in-and-of itself and I’d honestly love to be convinced that it should be removed).
I see; so you’re less concerned about legal liability, and more concerned with preventing
event-stream
-like attacks and the negative fallout on your team that might follow. Sure, that makes sense.I concede that you do have a pretty good reason. There is still a case to be made for removing it though:
Using shrinkwrap for this purpose is not commonplace; there is no social expectation of libraries taking steps to prevent malicious packages from making their way into a project. No reasonable person could possibly blame your team if something like that happened.
Projects must be responsible for their own dependencies, including transitive dependencies. At best, your team could prevent malicious packages from being brought into a project via ganache, but of course that’s not enough. Projects must also ensure non-ganache dependencies aren’t malicious. Any responsible project must already be taking steps to prevent this, either by waiting a while before making non-essential updates (as you do), or auditing each one, or some combination of those strategies. If not, they’re not safe.
Moreover, you’re not even necessarily making this task easier on projects, as you’re increasing the number of packages that need to be checked (unless they’re willing to wholly trust your team, which might not be justified for an outsider that doesn’t know how your team operates, and hasn’t established trust). In practice most projects don’t even strive to be this diligent, so you’re clearly reducing the chances of a malicious package attack in most cases by shipping a shrinkwrap file. But among the small number of projects who are similarly diligent, you may be making their task more difficult.
Using a shrinkwrap file can prevent projects from updating packages to address security vulnerabilities. Your team do do a fairly good job of keeping up on these, and I appreciate the standing offer to submit PRs to address them, but I can’t take advantage of that without updating
ganache
as well. That’s not always an option. Right now for example, I’m using an older version ofganache
and my tests break when I update (possibly due to a bug inganache
, but more likely we’re relying on a bug that you fixed). So I’m forced to decide between investing a great deal of time and effort now in updatingganache
, leaving the security advisory unaddressed, or pursing some workaround. I’d rather that I wasn’t put in that position.This approach of using a shrinkwrap file to slow down updates, as a means of preventing
event-stream
-like attacks, sets a bad precedent, and it would be bad if the rest of the community followed suit. On the one hand it is admirable that you care about this problem, and that you’ve gone to such lengths to solve it, but on the other hand it’s ultimately bad for the ecosystem for project maintainers have less control over their dependencies. This is especially true of library maintainers that are less diligent than you in reacting to vulnerabilities like that ENS one. Even if you can make it work, it’s the wrong way for the ecosystem as a whole to tackle this problem. It seems thatnpm
feels the same way, as they’re actively discouraging this.The workarounds are imperfect. The
--no-shrinkwrap
flag for example seems to not update the lockfile at all when I use it? (possibly just a bug withnpm
- not entirely sure how this is supposed to work though). No such flag exists withyarn
.yarn
does have another workaround (yarn resolutions), but it would be extremely tedious to use resolutions to change each dependency of a large project like this. Ultimately most projects won’t use a workaround for one reason or another, meaning they’ll be affected by problems I mentioned earlier of increased number of dependencies and outdated dependencies.Using shrinkwrap is more work for you and your team.
None of this invalidates the reason you outlined for using shrinkwrap; you have a good reason and I won’t dispute that. But there are substantial downsides. Either way, thanks for hearing me out.