You have to chose one of the two evils; automatic bug/vulnerability fixes, or protection against rogue OSS devs you depend on. I'd say the former is an order of magnitude more common and important, and so the npm/JS world works this way.
You have to chose one of the two evils; automatic bug/vulnerability fixes, or protection against rogue OSS devs you depend on. I'd say the former is an order of magnitude more common and important, and so the npm/JS world works this way.
NPM will by default create a lockfile that pins the dependencies. `npm install` will install dependencies from the lockfile as long as package.json hasn't been updated, or update the lockfile if it has. `npm ci` will install from the lockfile and fail hard if it can't satisfy the version constraints in package.json.
imo this gives the best of both worlds: Easy, controlled updates to the latest compatible versions and stable CI/CD.
The reason color.js was an issue is because people use `npm install` in their CI and either don't commit their lockfiles or have their lockfile inadvertently out of date—It's easy to do and I'm not sure how many people actually know about `npm ci`.
0: https://github.com/actions/cache/blob/main/examples.md#node-...
There is a problem here: it will update the __entire__ package-lock.json file, regardless of the actual changes in packages.json.
Pinning doesn't help here if colors dependency is not your direct dependency.
So you can have a pinned library that doesn't pin colors.js. Now you make a change in packages.json (say adding or removing another unrelated package). You will end up with colors being bumped to latest.
I'm so happy I don't need to fight npm anymore.
What the actual fuck. Who designed this fucking tire fire? Are you kidding me? What even is the point of package-lock.json??
I can't believe this. I actually can't. Now I have to audit all our dependencies, thanks.
Im told poetry fixes this, but havent checked it myself
- `npm update` should update the lockfile
- `npm upgrade` should update the versions in package.json
Yes, that is the problem.
> people use `npm install`
Yes and not just in the CI but also to install CLI tools user wide on a system and similar.
> not sure how many people actually know about `npm ci`
Idk. either but `npm install` had been the default for years, and a lot of documentation is based on it. Not deprecating `npm install` or changing it's behavior is typical for the npm ecosystem, i.e. having subtle sometimes UX related security issues (at least in my experience, I doubt it got much better).
The reality here is that just grabbing and running random shit on clients or servers has _always_ been unsafe. The people not pinning and mirroring have gigantic exposure. Pinning and mirroring people have some exposure. None of them should be doing what they are doing now.
That is what this whole catastrophic mess has been based on from day one.
Do not use NPM for anything new. Let it die a natural death.
The issue is that a broad swath of tech companies have thousands of instances of software that they've never even casually inspected running in user web browsers and in their back end servers, in contexts that are almost never locked down (network controls and segmentation, privilege reduction/separation, CSPs, etc.).
We are one malicious party from a broad total disaster.
This is a really broad problem. Focusing on NPM, which I agree is a trashfire, is kind of missing the problem.
NPM offers the same functionality with lock files.
If you have ~1.0.0 in package.json and 1.0.11 specified in the lock file, but then bump package.json to ~1.0.12, yes npm will upgrade the package and then bump the dep in your lock file to 1.0.12. That seems fine?
If you have `^1.0.0` in package.json, the version mark is `^1.0.11` in the lock file, which means that a random `npm i` or `yarn install` will install `^1.0.12` in your lock file.
I more or less said this yesterday[1], but the behaviour of `yarn install --frozen-lockfile` and `npm ci` should be the _default_ behaviour. The current behaviour is demonstrably dangerous. A lockfile should remain locked without explicit action by developers.
That's not true. package-lock.json file dependencies are specified as exact versions, not ranges. If you have 1.0.11 in your lock file, npm install will always install 1.0.11 unless it no longer satisfies the version in package.json.
“The presence of a package lock changes the installation behavior such that:
The module tree described by the package lock is reproduced. This means reproducing the structure described in the file, using the specific files referenced in "resolved" if available, falling back to normal package resolution using "version" if one isn't.
The tree is walked and any missing dependencies are installed in the usual fashion.”
The _only_ correct behaviour for a lockfile is `=1.0.11` (I think that npm calls that `1.0.11`, but NPM’s semver specification is unnecessarily complex compared to Elixir or Ruby) unless there is an explicit update. Otherwise, you will _not_ get the same version installed for all developers.
NPM lockfiles can't indicate `^1.0.11` so I believe this is where you're mistaken. They point to a specific version (`=1.0.11`) just like you're saying they should.
Could you describe a scenario where you think this happens? It doesn’t if you have a lock file in version control. Do you mean if it’s not in version control?
I mean it doesn't even really have support for proper package versioning, instead it just magically hacks the environment. Which happens to work, but is also kinda a nightmare.
I have no idea why python programmers still mostly accept that as a viable solution.
Short of downloading individual jar files without the original source code.
They are still not perfect, but they tend to know it and work on improving it (almost often slow).
The problem tends to be more around missing proper CI setups and workflows(1) and similar. And naturally npm being very easy to use wrongly.
(1): Lock versions, (shallow) review diffs of most dependency bumps, test and build in a sandbox, automatically check CSV/audit databases on frequent basis, don't automatically bump versions of release builds, etc., etc.
> carefully selected but outdated distro repos.
and also:
- inconsistent between distros
- sometimes long term unfixed security vulnarabilities
- (more) incompatibilities between packages and distroes
- unofficial patches to fix security vulnerabilities or compatibility, which not seldom cause future subtle problems, including security problems
-problems to push important security fixes in time
-often not language specific due to the high amount of work needed to properly maintain them
- costly to operate
- an additional attack-able link in the supply chain
- often OS specific
A distro based system is quite nice for distributing programs, but in my experience it's a nightmare for software packages.
I mean just look at the endless problems distros have with packaging python, npm and shared objects.
Instead I think most dependencies should always be bundled with the program (if anyone can rebuild if needed, i.e. open source) and distros should only package programs, not libraries.
There are some exception. But like less then 10 on most Linux systems, and many could adept by having a well defined non C-FFI interface + bundled support library.
Personally I think there is a business model in there. "Curated" code releases/versions by a trusted third party you pay to review all the code. It would be a boring job, like being an auditor.
Bonus points, you can pay an "ethical" one that then tries to get money to the OSS devs of libraries that their clients demand the most.
Which is apparently more than most of the coders out there.
I would say blindly pulling _any_ code from _anywhere_ is a liability.
No matter of weather it comes from or weather it's open source or a proprietary vendors library.
Something like "I trust NPM so accept all releases that NPM has approved". Large companies could have their own internal approval keys etc.
It is really good, allowing for distributed reviews, not necessarily from the people authoring your dependencies. The OP suggests that if you -> A -> B, the package manager should only install versions of B vetted by A (or close); I think this doesn't scale well in practice (all the more so if the only way A can vet a new version of B is by doing a new release). Having the possibility to rely on other people to vet releases (possibly in your company) opens a lot of doors, such as the ability to not trust the author of A at all.
This would handle both Log4Shell and colors/left-pad issues. Additionally, a repository owner could force a mandatory package update without the author's consent, in case someone hides malicious code in their package and it becomes popular.
Of course the repository owner could go rogue, but I trust NPM/Maven/Cargo/OPAM maintainers much more than a random package developer.
What about human errors introduced by non-rogue developers? (a reasonably common occurrence, probably?)