Skip to content

Conversation

@PR3C14D0
Copy link

@PR3C14D0 PR3C14D0 commented Dec 3, 2025

Summary

This PR implements a minimum package age policy feature for npm, similar to pnpm's minimumReleaseAge (pnpm/pnpm#9921). This security feature helps protect against supply chain attacks where malicious package versions are published and then quickly removed from the registry.

Motivation

Recent supply chain attacks have shown that malicious actors often publish compromised versions of popular packages and remove them within hours after causing damage. By enforcing a minimum age requirement, users can avoid installing versions that haven't been publicly available long enough to be vetted by the community.

Changes

New Configuration Options

  • minimum-release-age (Number, default: 0)

    • Specifies the minimum age in minutes that a package version must have before it can be installed
    • When set to 0, the policy is disabled (default behavior)
  • minimum-release-age-exclude (Array, default: [])

    • List of package names that should bypass the minimum age policy
    • Useful for trusted packages where immediate updates are needed

Implementation Details

  1. Configuration - Added definitions for both new options in the config definitions module
  2. Dependency Resolution - Modified the manifest fetching logic in Arborist to:
    • Fetch full packument to access version timestamps
    • Calculate cutoff time based on configured age
    • Add recent versions to pacote's avoid option
    • Gracefully handle errors (skips policy if packument fetch fails)
  3. Documentation - Added comprehensive documentation with usage examples
  4. Tests - Added 4 test cases with 9 assertions covering all scenarios

Usage Examples

Via .npmrc:

minimum-release-age=1440  # 24 hours
minimum-release-age-exclude[]=@myorg/trusted-package

Via CLI:

npm install --minimum-release-age=10
npm install some-package --minimum-release-age=60 --minimum-release-age-exclude=critical-package

Via environment variable:

npm_config_minimum_release_age=10 npm install

Testing

All tests pass:

✓ 4 test suites (9 assertions)
✓ Linting passes

Test coverage includes:

✅ Basic policy enforcement (avoids recent versions)
✅ Exclusion list functionality
✅ Disabled policy (minimum-release-age=0)
✅ Error handling (packument fetch failures)

Breaking changes

None. This is a purely additive feature with default behavior unchanged (policy disabled by default).

Related issues

Inspired by pnpm/pnpm#9921

Add support for minimum-release-age configuration option to enforce
a waiting period before installing newly published package versions.
This helps mitigate supply chain attacks where malicious versions are
published and quickly removed.

Changes:
- Add minimum-release-age config option (default: 0, disabled)
- Add minimum-release-age-exclude config option for exemptions
- Implement version filtering in Arborist's #fetchManifest method
- Add comprehensive test coverage (4 tests, 9 assertions)

The policy works by:
1. Fetching the full packument for each package
2. Calculating a cutoff time based on the configured age
3. Identifying versions released after the cutoff
4. Adding them to the 'avoid' range passed to pacote

Users can configure via .npmrc, CLI flags, or environment variables:
  minimum-release-age=10
  minimum-release-age-exclude[]=critical-package

Files modified:
- workspaces/config/lib/definitions/definitions.js
- workspaces/arborist/lib/arborist/build-ideal-tree.js
- workspaces/arborist/test/arborist/minimum-release-age.js (new)

Inspired by pnpm's minimumReleaseAge feature (pnpm/pnpm#9921)
Add documentation for:
- minimum-release-age configuration
- minimum-release-age-exclude configuration
- Usage examples and security benefits"
@wraithgar
Copy link
Member

This is already being explored in an existing PR #8802

@wraithgar wraithgar closed this Dec 3, 2025
@loudar
Copy link

loudar commented Dec 4, 2025

This is already being explored in an existing PR #8802

The other PR doesn't seem to have an option to exclude specific packages from the rule though?

@passee
Copy link

passee commented Dec 4, 2025

@wraithgar there is no exclude option available in the pr you mentioned

@PR3C14D0
Copy link
Author

PR3C14D0 commented Dec 4, 2025

This is already being explored in an existing PR #8802

The PR #8802 it does not have an exclude package option. Mine is a minimal implementation that can be extended during the time and improve it and maybe an implementation at package.json.

I would consider accepting this pull request and not closing it immediately as you did, and extending the implementation. It's one of the most requested security policies in recent times.

@fabianmartinezcaro
Copy link

fabianmartinezcaro commented Dec 5, 2025

thi shit is more robust than #8802, fr fr. @PR3C14D0 congrats bro

@fabianmartinezcaro
Copy link

fabianmartinezcaro commented Dec 5, 2025

Speechless, bro is cooking

@mikkelee
Copy link

mikkelee commented Dec 5, 2025

I vote for all pull requests that implement a quarantine period and allow specifying packages that can skip quarantine. I have no opinion on the naming of the configuration keys because I will not be looking at them more than once a month at most. To be clear, and in case of ties with other pull requests: consider this a vote for the concept in general and all of them together.

@PR3C14D0
Copy link
Author

PR3C14D0 commented Dec 5, 2025

I vote for all pull requests that implement a quarantine period and allow specifying packages that can skip quarantine. I have no opinion on the naming of the configuration keys because I will not be looking at them more than once a month at most. To be clear, and in case of ties with other pull requests: consider this a vote for the concept in general and all of them together.

Anyways, this is not a competition hmmm ☹️

@pemasat
Copy link

pemasat commented Jan 13, 2026

So, you closed it without the right solution? The linked PR is not so a good solution as someone mentioned here, plus it is still in not-merged status. We still don't have a correct solution as protection against attacks. This is a really sick solution, and finally, more developers say "bye-bye npm"

@ljharb
Copy link
Contributor

ljharb commented Jan 13, 2026

This isn't actually useful protection against these attacks.

@pemasat
Copy link

pemasat commented Jan 14, 2026

This isn't actually useful protection against these attacks.

So, what do you have as a solution for a chain attack? Date/time protection sounds like a good step for me, and you blocked it now.

@ljharb
Copy link
Contributor

ljharb commented Jan 15, 2026

I didn't block anything; I lack that power here.

The "solution" (short of actually funding maintainers) is lockfiles, tools that update them for you, tools that scan them for you, and thorough human review - same as it ever was.

@PR3C14D0
Copy link
Author

PR3C14D0 commented Jan 16, 2026

I didn't block anything; I lack that power here.

The "solution" (short of actually funding maintainers) is lockfiles, tools that update them for you, tools that scan them for you, and thorough human review - same as it ever was.

If the solution is lock files, then #8802 shouldn't look good to you too. We both (8802 & 8825) are proposing a solution with the time. Also pnpm or bun, they do the same as these solutions. It's a SECURITY thing and some solution is needed.

We are not asking for a full implementation, only a temporal hot fix that can evolve into a feature that makes us more secure when using NPM.

It's really sad to see one of the most worldwide used project start to be in decadence because of these security issues and people change to other tools as pnpm or similars.

@ljharb
Copy link
Contributor

ljharb commented Jan 16, 2026

It doesn't look good to me either. Using a "minimum age" policy is foolish and will not meaningfully protect anyone, and if enough people do it, will worsen things for the ecosystem.

"in decadence" is wildly inaccurate anyways.

To be more secure when using npm, there is no shortcut or silver bullet. You must, forever, review your dependency updates, use lockfiles, and ensure open source maintenance is sustainable. That's the solution.

@mikkelee
Copy link

counterpoint: security is a two-way street. of course, users and developers should be security-minded, but given that many are not, the tools and eco-systems have to provide some mitigations

most recent supply-chain attacks only (partially) succeeded because the compromised packages fit the version spec. yea sure, lockfiles, but can you honestly say that you read every diff in every package before you update it to your lockfile?

imo its a very open source thing to spread out the risk among all the users. we dont all update or deploy at the same time, so different delays among all of us effectively works as canaries. until we fix the harder problem of making hacking impossible.

but even if you dont agree, whats the harm? why not let individual orgs/devs just say "im ok with a 1 week delay"? its hard to imagine that it would cause more harm than the status quo

@ljharb
Copy link
Contributor

ljharb commented Jan 16, 2026

because once enough people do it, that will just delay discovery of the problem by a week.

@uiii
Copy link

uiii commented Jan 16, 2026

because once enough people do it, that will just delay discovery of the problem by a week.

I think this is not true. This will at least create some time for package authors to be able to revert the attack. More time to see changes before it spreads. Not sure how companies like Snyk, Socket etc. work but if the automatically scan whole npm registry, there will also be time for it.

@mikkelee
Copy link

problems are currently only being discovered when either (a) an exploit is actively in the wild, or (b) some scanning service catches it in a recent npm package update. nobody has time to go over every change.

anyway in either case, slowing down package adoption by a week will cause less damage. without "staggered rollouts" (as it is now), everyone who updated in that period would be affected. with them (the proposed change), maybe half

(tbf, the latter half did not get the cleanup patch where i fixed up some comments and pulled a few functions out to a helper library, but did they really need that? if they did, they should have used the default settings and not used the proposed setting)

@PR3C14D0
Copy link
Author

PR3C14D0 commented Jan 17, 2026

counterpoint: security is a two-way street. of course, users and developers should be security-minded, but given that many are not, the tools and eco-systems have to provide some mitigations

most recent supply-chain attacks only (partially) succeeded because the compromised packages fit the version spec. yea sure, lockfiles, but can you honestly say that you read every diff in every package before you update it to your lockfile?

imo its a very open source thing to spread out the risk among all the users. we dont all update or deploy at the same time, so different delays among all of us effectively works as canaries. until we fix the harder problem of making hacking impossible.

but even if you dont agree, whats the harm? why not let individual orgs/devs just say "im ok with a 1 week delay"? its hard to imagine that it would cause more harm than the status quo

I agree with you, also, its an optional policy delaying the package updates and there is people that won't use it and if there is a vulnerability or exploit, the range of people attacked will be less than without any policy. And it would be detected if there is people that doesnt even use it

And now is more important because a lot of people Vibe-code and dont even know what a dependency is even what is npm

@PR3C14D0
Copy link
Author

PR3C14D0 commented Jan 17, 2026

As a C++ Developer I would like to say that the solution of checking all the changes one by one, in C++ is valid because we usually compile all the libraries by ourselves (in most of the cases), and you usually review the code for asserting there is nothing strange that can cause any damage. But in JS/TS??? Most of developers dont even cares about subdependencies.

I saw enterprises that move a lot of money having dependencies deprecated 7 years ago.

Its like asking a blind to see colors

@mikkelee
Copy link

mikkelee commented Jan 17, 2026

As a C++ Developer I would like to say that the solution of checking all the changes one by one, in C++ is valid because we usually compile all the libraries by ourselves (in most of the cases), and you usually review the code for asserting there is nothing strange that can cause any damage. But in JS/TS??? Most of developers dont even cares about subdependencies.

I saw enterprises that move a lot of money having dependencies deprecated 7 years ago.

Its like asking a blind to see colors

agreed

btw, sorry bro i stole some creds and pushed a dogshit commit to the cpp stdlib. seymour.gif

oh hell, they figured it out immediately, before anybody even got it deployed. sigh. im just so tired of developers using tools to verify contributions ;_;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants