> "'No Way to Prevent This,' Says Only Nation Where This Regularly Happens" is the recurring headline of articles published by the American news satire organization The Onion after mass shootings in the United States.
Source: https://en.wikipedia.org/wiki/%27No_Way_to_Prevent_This,%27_...
Well before the npm attacks were a thing, we within the Rust project, have discussed a lot of using wasm sandboxing for build-time code execution (and also precompiled wasm for procedural macros, but that's its own thing.) However the way build scripts are used in the Rust ecosystem makes it quite difficult enforce sandbox while also enabling packages to build foreign code (C, C++ invoke make, cmake, etc.) The sandbox could still expose methods to e.g. "run the C compiler" to the build scripts, but once that's done they have an arbitrary access to a very non-trivial piece of code running in a privileged environment.
Whereas for Javascript rarely does a package invoke anything but other javascript code during the build time. Introduce a stringent sandbox for that code (kinda deno style perhaps?) and a large majority of the packages are suddenly safe by default.
You can vendor your left-pad, but good luck doing that with a third-party SDK.
I maintain that the flexibility in npm package versions is the main issue here.
You still need some out-of-band process to pull upstream updates and aside from a built-in “cool down” (until you merge changes) I see that method as having a huge amount of downside.
Yes, you sidestep malicious versions pushed to npm but now you own the build process for all your dependencies and you have to find time to update (and fix builds if they break) all your dependencies.
Locking to a specific version and waiting some period of time (cool down) before updating is way easier and jus as safe IMHO.
[redacted bullshit!]
I'm confused on this. I would imagine it would protect/help you as long as releases are immutable which they are for most package managers (like npm).
> Vendoring literally just means grabbing the source code from origin and commit it to your repo after a review.
Hmm, I don't think it always necessarily means grabbing the source, it can also mean grabbing the built artifacts in my experience.
My biggest issue with vendoring dependencies is it allows for editing of said dependencies. Almost everywhere I've worked that vendored dependencies (copied source or built versions in and committed them) felt the siren song of modifying said dependencies which is hell to deal with later.
I personally don't have a problem with the general ability to change vendor code. The question is whether you want it in an specific case or not. If you update frequently then certainly not. But that decision should be deliberate team policy.
Fair, in the instances I ran into it was code that was downloaded and unzipped into a "js-library-name" folder but then the code was edited, even worse, the `.min.js` version wasn't touched, just the original one which led to some fun when someone "helpfully" switched to the min versions that didn't have the edit. IMHO, if you want to edit a library then you should be forking and/or making it super obvious that this is not "stock" library X. We also ran into issues with "just updated library Y" and only later realizing someone had modified the older version.
But yes, if it's deliberate and obvious then I don't have an issue modifying, just as long as the team understands it's "their" code now and there is no clean upgrade path in the future.
The difficulty to make changes obvious is same for forks and vendored commits, imho. You can write big warnings in commit messages, that's it I guess. Which kind of boils down to deliberate team policy again. But I generally prefer monorepos for various reasons.
Another example: all Debian packages are published to unstable, but cannot enter testing for at least 2-10 days, and also have to meet a slew of conditions, including that they can be and are built for all supported architectures, and that they don't cause themselves or anything else to become uninstallable. This allows for the most egregious bugs to be spotted before anyone not directly developing Debian starts using it.
Hate to break it to you but from targeting enterprises, java maven artifacts would be a MASSIVE target. It is just harder to compromise because NPM is such shit.
This adds a bit more overhead to typo squatting, and a paper trail, since a domain registrar can have identity/billing information subpoenaed. Versus changing a config file and running a publish command...
You can definitely do this.
To be honest, you just end up with the same thing via dependabot/renovate.
You can specify a dependency version range in Maven artifacts. But the Maven community culture and default tooling behaviour is to specify exact versions.
You can specify an exact dependency version in npm packages. But the npm community culture and default tooling behaviour is to specify version ranges.
Even if a maintainer uses a bot to bump dependency versions, most typically they will test if their package works before publishing an updated version, and also because this release work is manual (even if the bot helps out), it takes some time after the dependency is released for upstream consumers of it to endorse and use it. Therefore, nobody consuming foo 1.0.4 will use dependency bar 2.3.5 until foo 1.0.5 is released... whereas an npm foo 1.0.4 with bar dependency "^2.3.0" will give its users bar 2.3.6 from the very moment bar 2.3.6 is released, even without a foo 1.0.5 release.
https://bootstrappable.org/ https://reproducible-builds.org/ https://github.com/crev-dev
This does not prevent said package from shipping with malware built in, but it does prevent arbitrary shell execution on install and therefore automated worm-like propagation.
As a SW developer, you may be able to limit the damage from these attacks by using a MAC (like SELinux or Tomoyo) to ensure that your node app cannot read secrets that it is not intended to read, conns that it should not make, etc. and log attempts to do those things.
You could also reduce your use of external packages. Until slowly, over time you have very little external dependencies.