54 comments

[ 2.3 ms ] story [ 83.2 ms ] thread
didn't know npm was owned by github.. well, that explains things...
I knew it was owned by github, but this is the first time I've personally seen the release notes on github's blog instead of npm's.
I hope GitHub changes their vibecoded badges, what does RETIRED even signify in this context? Why does the preview have to be in ominous red?
Looks good? But doesn't this just change the compromise window from first installation to first run?
They should have added a 1-day age limit by default, so security scanners have some time.
LLMs are reducing n-day exploit time rapidly.

https://red.anthropic.com/2026/n-days/

So that is a poor bandaid to use now. Maybe instead validate things before, and have more of a cathedral and human reputation system.

I would have been fine with 24 hours but some of my co-maintainers asked for longer.

Which was a little weird for the modules that don't run standalone but whatever.

Eh, that only took a few dozen actively exploited supply-chain vulns in the span of two years!
> The resulting allowlist is written to package.json

Couldn’t this effectively result in the same process we get in pre-12 defaults?

It is not obvious from the post but it seems like the allow list for the scripts supports whitelisting packages instead of a global setting. This should make it easier to maintain org-wise rules to allow scripts only for specific packages.

Is there a linter that could be used for scenarios like this to prevent unsafe default on package manager config?

My big question as an OSS dev distributing some precompiled binaries via npm for easy installation: does allowScripts also default to disabled when directly installing a package (globally or otherwise)?
Yes, all install scripts will be disabled by default regardless of if they are from direct or transitive dependencies.

But if you're already following the os + cpu + optionalDependencies model to distribute your precompiled binaries you should be fine.

The "aw geez, enough is enough" release.

Finally.

> allowScripts defaults to off

Nice that they're following pnpm's lead on this after [checks watch]... 18 months?

I bet there have been a hundred different discussions about this inside of NPM since it was disclosed 10 years ago. With Shai Halud it's gotten too big to ignore.
I do love that javascript's history is basically just coder mentality distilled. "oh yeah we'll fix that shortly" is almost always "oh fuck now we have to"
(comment deleted)
I would've assumed lockfile-by-default. We're still going with auto-updating?
There's an easy way to stop most supply chain attacks:

1. Publishing users must approve each and every release from a smartphone app.

2. Publishing users must provide verified government ID.

The first step prevents the types of attacks where an attacker gets control of a maintainer's computer and publishes a new release.

The second step discourages attacks where a user tries to get a malicious package used by others.

When combined with the security features that already exist, e.g. delays and automatic scanning, it would make it considerably harder to pull off a successful attack.

Issue is this is such a pain (and shuts out a large percentage of the world population) that you'll inevitably get a parallel ecosystem of packages without these onerous controls that everyone would end up using.

I don't know how to square the circle but any variation of "make it safer but really painful and difficult for anyone to publish a package" has this problem

How would this prevent Shai Halud?
I don't get it. How does this help with anything? You pull in a dependency to use it, right?
How do you allow scripts for tools installed globally?
Either pass the --allow-scripts=<pkg> flag with npx or npm install -g, or set allow-scripts=<pkg> in .npmrc
Does the allow list in package.json pin to the package version, or only to the package name?
What a pointless change.

If you force every user to just use "--enable-unsecure-feature", guess what will happen?

This is not about improving security. This is about shifting blame.

A much better alternative would've been the introduction of sandboxes or simulation runs that would output which scripts and programs are running due to unpredictable dependencies. This way the user could check before the actual execution, and maintain an allow list much easier. That could be done via an npm update && npm upgrade workflow where the update generates the list that the user has to manually confirm.

Heck, even a chroot would be an improvement, and they're almost pointless these days, considering how good malware got at escaping chroots.

I don't think it's pointless. A large number (the majority?) of users probably don't need install scripts, so disabling them by default is a net security improvement. Those that do can enable the insecure behavior, which will become an explicit decision that is trackable, auditable, etc.

You're not wrong about sandboxing, but sandboxing isn't something that can just be blithely introduced to a large packaging ecosystem that previously assumed full system access. Doing so results in the same kind of regression you point out: if the sandboxing breaks peoples' builds, they'll just disable it and move on with their goals.

Most users don't need it. Having it on by default is a feature for malware writers not users.

But to your point, Node has had permission flags for a while[0] but allows everything by default. Npm could use them to increase security even more. I just hope it doesn't take them another 10 years to change the default.

[0] https://nodejs.org/api/permissions.html

This is kind of like arguing that immutable by default variables are pointless.

If you force every user to just write "mut", guess what will happen?

They will write "mut" when they need mutable variables, which in practice turns out to be the minority of variables.

It's the same with "Option". The vast majority of variables or struct members do not need to be nullable at all.

This is pip with --break-system-packages heh
And when will we get rid of the vendored node_modules, and make it read only?
Are the current LTS node versions (iirc 22, 24, 26) going to update the bundled npm to v12 to benefit from these security fixes? All come with npm v11 now
I wonder if there are still reasons to use yarn? Has yarn also implemented safeguards to protect against supply chain attacks? Until now, I only knew about pnpm. It’s great that npm has followed up.
Though I mostly use pnpm these days, yarn still has a feature that I frequently miss: the project-local cache[0]. Basically, every dependency archive fetched from a registry is stored in your repo in .yarn/cache, so unless you're adding/updating dependencies a `yarn install` will work fully offline.

I'm sure there are drawbacks to this method regarding repo size etc., but it just feels good knowing that my repo contains everything needed to install and run any version of my project.

[0]: https://yarnpkg.com/features/caching#offline-mirror

I should add: this is enabled by adding `enableGlobalCache: false` to .yarnrc.yml, though I think it was the default for a bit when Yarn 2 first released.