Reminder to secure your npm environments.

https://gajus.com/blog/3-pnpm-settings-to-protect-yourself-f...

Just a handful of settings to save a whole lot of trouble.

In aube you get all this out of the box plus a lifecycle jail (next MV will have that on by default) and defaults to trustPolicy=no-downgrade (would not have helped here but still a good default).

It has the strongest security posture of any node pm.

https://aube.en.dev/security.html#jailed-lifecycle-scripts

Heads up: Your website at en.dev says you're a one-person open source company. That immediately ruled out any of your tools for me and my team; no matter how great they may be, a single developer is a supply chain risk. I wholeheartedly recommend enlarging the team.

What a pleasant surprise to see jdx within comments! I was actually using mise and found aube and decided to publish it on hackernews, I found it really cool!

Though a bit sad that it hadn't received traction back then but I must admit jdx that a lot of the work that you do is really cool.

Also I am happy to know that you are finally able to work on Open source full time, I am glad that I can use open source software created by (in my opinion generous) people like you too, mise is awesome :-D

https://news.ycombinator.com/item?id=48012248

Wild claim that setting the minimum age to 7 days will result in me "never" getting a supply chain npm vuln.

In this case it would have, because the compromised packages were pulled within 3 hours.

This sort of mitigation seems like it makes sense in the short term, but it seems like it would only work as long as most people don't do it. If everyone has this set to seven days, it will take seven days plus three hours to get things yanked, and then there will be people who will set to 14 days...

No, its still a very useful mitigation tool.

1) Package owners will often realise they've been hacked quickly, since there are releases they never authorised. This gives them plenty of time to raise the alarm and yank the packages

2. Independent security researchers and other automated vulnerability scans will still be checking the latest releases even if users aren't using them

Yes it's not a perfect defense but it would help a lot.

Some people would set up tooling to look for compromises the moment they get published. What's neat about this is that as an attacker you have no way to determine beforehand whether you'll get caught by this. So you would run your attack, it would lead to a compromised package being published, then the world would get a chance to look at it and see if they can detect the issue with it. This would of course lead to attackers being a lot sneakier. But I think due to the opaque nature of what checks people are running against packages and what they might notice, a much smaller number of attacks would make it through. Of course the ones that did by definition would be the ones that were impossible to detect and would thus stick around a lot longer.

These malicious packages are being caught by the authors, and by automated package security scanners, not just by end users. npm should start setting this 7 day cooldown as default.

Even 12 hours would probably be enough. Those automatic malware scanning companies are getting really fast.

Mine's set to 1 day (seems to be enough from all the cases we've learned about), I got you.

Also seems like this attack and most others were caught by automated tooling from 3rd parties

you are betting that the package is popular, has enough eyes to mitigate attack in 7 days. attackers could also target unpopular packages for long game

There is a “fresh” in there

[deleted]

Isn't this article wrong about npm minumum release age. 1. The config is min-release-age. 2. For some reason they have chosen to make it days instead of minutes: https://docs.npmjs.com/cli/v11/using-npm/config#min-release-...

Completely unforced fragmentation of the dependency manager space imo

This confused me too, until I realized that the article is about pnpm, not npm (pnpm reads .npmrc for some reason, despite not having the same options as npm)

On a related note, it seems to be impossible to find the documentation of min-release-age by googling it. Very annoying.

I just set this up for npm, here's the command that worked for me:

npm config set min-release-age 7

The '7' is days. This is the only format that worked for me, just a single integer number of days.

Confirmed by trying to install the latest version of React 19.2.6 (published 5 days ago as of the time of this comment). It failed with a comment confirming that it could not find such a version published before a week ago.

Unfortunately there is currently an issue in pnpm that makes `minimumReleaseAge` difficult: https://github.com/pnpm/pnpm/issues/11068

And absolutely pin, pin, pin, ALL your dependencies.

If I see a package version dependency that looks like this: ^1.0.0 or even this: "*", then stop reading, pin it to a secure version immediately.

Npm's package-lock.json already handles pinning everything to exact versions, including subdependencies. Pinning exact versions in package.json doesn't affect your subdependencies.

You aren't wrong. However, this article does offer some additional advice on this matter, and some potential reasons why it might still be desirable to pin your deps in package.json.

https://docs.renovatebot.com/dependency-pinning/#pinning-dep...

Some exerts:

> If a lock file gets out of sync with its package.json, it can no longer be guaranteed to lock anything, and the package.json will be the source of truth for installs.

> provides much less visibility than package.json, because it's not designed to be human readable and is quite dense.

> If the package.json has a range, and a new in-range version is released that would break the build, then essentially your package.json is in a state of "broken", even if the lock file is still holding things together.

Or help distributions do the manual process of packaging - which involves at least rudimentary security checks - so they can ship newer versions faster.

And then use distro packages.

(I'm not accepting distro fragmentation as counterargument. With containerization the distro is something you can choose. Choose one, help there, and use it everywhere.)

Are you talking about in package.json? What's your threat model? That's what the lock file is for, which also pins transitive dependencies, which is just as crucial. Now what's actually insecure is if you don't commit the lockfile. and if you don't do `npm ci`.

I think `npx` might pull down new versions, too? I wish npm worked more like Elixir where updating the lock file was an explicit command, and everything else used the lock file directly.

its so wild to have seen this advice reverse course over the past year.

it used to be that projects that pinned deps were called out as being less secure due to not being able to receive updates without a publish.

different times, different threat model I suppose

> it used to be that projects that pinned deps were called out as being less secure due to not being able to receive updates without a publish.

This is still the right advice for libraries. For security it doesn’t matter a whole lot anymore as package managers can force the transitive dependencies version, but it allows for much better transitive dependency de duplication.

For non-libraries it doesn’t matter as the exact versions get pinned in the package-lock.

I've been collecting things you can't pin:

- Python inline dependencies in PEP-0723, which you can pin with a==1.0, but can't be hash-pinned afaik.

- The bin package manager lets you pin binaries, but they aren't hash-pinned either.

- The pants build tool suggests vendoring a get-pants.sh script[0] but it downloads the latest. Even if you pass it a version, it doesn't do any checks on the version number and just installs it to ~/.local/bin

[0]: https://github.com/pantsbuild/setup/blob/gh-pages/get-pants....