显示HN:Safe-NPM – 只安装发布超过90天的包
Show HN: Safe-NPM – only install packages that are +90 days old

原始链接: https://github.com/kevinslin/safe-npm

## Safe-npm:保护您的项目免受供应链攻击 Safe-npm 是一款注重安全的 npm 安装器,旨在缓解 npm 包被破坏日益增长的威胁。它的工作原理是**仅安装已公开存在至少一定时间(默认 90 天)的软件包版本**,从而为安全社区提供时间来识别和报告恶意发布。 当您运行 `safe-npm install` 时,它会检查 npm 注册表,根据您指定的年龄阈值*和*语义版本控制 (semver) 要求过滤版本,然后安装最新的安全版本。您可以使用 `--min-age-days` 自定义最小年龄,并使用 `--ignore` 绕过对受信任软件包的年龄检查。`--strict` 标志可确保如果找不到安全版本,构建将失败。 **主要功能包括:** 模拟运行模式以预览更改、控制仅安装 `devDependencies` 或 `productionDependencies`,以及安装策略选项。 虽然 Safe-npm 并非万无一失的解决方案,但它为防御突发的供应链破坏增加了一层重要的保障,用牺牲对最新功能的即时访问来换取更高的安全性。最好将其与其他安全实践(如定期审计和依赖项审查)一起使用。

## Safe-NPM:一个注重安全的 NPM 客户端 最近的 npm 供应链攻击(如 Shai-Hulud 和 Chalk/debug 妥协)促使了 **Safe-NPM** 的创建,这是一种旨在降低风险的 CLI 工具。由 kevinslin 开发,Safe-NPM 仅在软件包公开可用至少 90 天(默认)后才安装 NPM 软件包。 它通过查询 npm 注册表,根据语义化版本范围过滤掉最近发布的版本,然后安装最新的“已老化”软件包。 虽然这并非万无一失的解决方案——它无法从一开始就捕获恶意软件包,并且目前无法解决传递依赖问题——但它为应对*最近*的妥协提供了一种快速防御。用户应注意,它可能会延迟访问最新功能和补丁。 Safe-NPM 可通过 `npm install -g @dendronhq/safe-npm` 获取,旨在提供一个 80/20 解决方案以提高安全性。
相关文章

原文

A security-focused npm installer that protects your projects from newly compromised packages.

Supply chain attacks on npm packages are a growing threat. Attackers sometimes compromise legitimate packages by:

  • Stealing maintainer credentials
  • Publishing malicious updates to popular packages
  • Taking over abandoned packages

These attacks often happen suddenly—a package that was safe yesterday might be compromised today. safe-npm protects you by only installing package versions that have been publicly available for a minimum amount of time (90 days by default). This gives the security community time to discover and report malicious releases before they reach your project.

When you run safe-npm install, it:

  1. Reads your dependencies from package.json or command-line arguments
  2. Queries the npm registry to find all available versions
  3. Filters out versions published more recently than your minimum age threshold
  4. Selects the newest version that meets both your semver requirements AND age requirements
  5. Installs the safe versions using npm

For example, if you specify react@^18 and a malicious [email protected] was published yesterday, safe-npm will install the latest version that's at least 90 days old instead.

Install from npm (recommended)

# Install globally
npm install -g @dendronhq/safe-npm

# Now you can use it anywhere
safe-npm install
# Clone and build
git clone <repository-url>
cd safe-npm
npm install
npm run build

# Link the binary globally
npm link

Install dependencies from package.json

# Use the minimum age of 90 days (default)
safe-npm install

# Or specify your own minimum age
safe-npm install --min-age-days 120

Install specific packages

# Install packages directly with version constraints
safe-npm install react@^18 lodash@^4.17.0

# These will be filtered to only use versions at least 90 days old
safe-npm install express --min-age-days 60

Dry run to see what would be installed

# Preview which versions would be installed without actually installing
safe-npm install --dry-run

Default: 90

The minimum number of days a package version must have been published before it can be installed.

Example: --min-age-days 120 requires packages to be at least 4 months old.

When to adjust:

  • Increase for maximum security (e.g., 180 days for critical production systems)
  • Decrease if you need newer features and accept slightly more risk (e.g., 30 days)

A comma-separated list of packages that bypass the age requirement. These packages will still respect semver ranges but ignore the minimum age.

Example: --ignore typescript,@types/node

When to use:

  • Fast-moving packages you trust (like TypeScript or build tools)
  • Internal packages from your organization
  • Packages where you need the latest features urgently

Exit with an error if ANY dependency cannot be resolved to a version meeting the age requirement.

Example: safe-npm install --strict

When to use:

  • CI/CD pipelines where you want builds to fail rather than skip problematic packages
  • Production deployments where you need certainty

Control which dependencies from package.json are processed.

Examples:

  • safe-npm install --dev - Only install devDependencies
  • safe-npm install --prod-only - Only install production dependencies

When to use:

  • Installing development tools with stricter requirements
  • Production builds where you want different age policies for dev vs prod dependencies

--strategy <direct|overrides>

Default: direct

How safe-npm installs the resolved versions:

direct - Directly installs the resolved versions using npm install package@version

  • Simple and straightforward
  • Good for one-time installs or scripts

overrides - Writes resolved versions to package.json overrides field, then runs npm install

  • Enforces versions across your entire dependency tree (including transitive dependencies)
  • Note: This feature is currently disabled as it doesn't work correctly yet

Default: https://registry.npmjs.org

Specify an alternate npm registry.

Example: --registry https://registry.company.com

When to use:

  • Private npm registries
  • Mirrors or caches

Show what would be installed without making any changes.

Example: safe-npm install --dry-run

When to use:

  • Testing your configuration
  • Understanding what versions are available
  • Before making changes to production systems
# Create a new project
mkdir my-project && cd my-project
npm init -y

# Install dependencies safely
safe-npm install express@^4 lodash

# This creates package-lock.json with versions at least 90 days old

Audit an existing project

# Check what versions would be installed with age requirements
safe-npm install --dry-run

# If you're happy, install them
safe-npm install
# In your CI pipeline, fail the build if any package can't meet age requirements
safe-npm install --strict --min-age-days 120

# Or allow newer packages for dev dependencies only
safe-npm install --prod-only --strict
# Need to urgently update a specific package? Add it to ignore list
safe-npm install --ignore package-with-critical-fix

The project includes a test suite that you can run:

For automated testing, you can mock registry responses using fixtures:

export SAFE_NPM_FIXTURES=/path/to/fixtures.json
safe-npm install

The fixtures file should contain JSON that mirrors npm registry responses for each package.

Real-world scenario:

  1. A popular package popular-lib is maintained by a trusted developer
  2. Attacker compromises the maintainer's npm credentials
  3. Attacker publishes [email protected] with malware
  4. Projects using ^5.0.0 would immediately install the malicious version
  5. With safe-npm, you'd keep using 4.9.0 (the latest version from 90+ days ago)
  6. Security researchers discover the compromise and report it
  7. The malicious version is unpublished
  8. You never installed the compromised version
  • Won't protect against packages that were malicious from the start
  • Delays access to legitimate new features and bug fixes
  • Requires trust that older versions don't have undiscovered vulnerabilities
  • Age-based filtering is a heuristic, not a guarantee

Security is about trade-offs. safe-npm trades bleeding-edge updates for protection against sudden supply chain compromises. It's one layer in a defense-in-depth strategy that should also include:

  • Regular security audits (npm audit)
  • Dependency review before adding new packages
  • Monitoring for security advisories
  • Using lock files to ensure reproducible builds
  • Running in sandboxed or containerized environments
  • Node.js 18 or higher
  • npm (for the underlying installation)

ISC

联系我们 contact @ memedata.com