CRBroughton/recul

GitHub: CRBroughton/recul

一个通过让npm依赖版本滞后于最新发布来降低供应链攻击风险的审计工具。

Stars: 0 | Forks: 0

# recul 让你的 npm 依赖版本滞后于最新发布版本 N 个版本,以避免供应链攻击。 recul 不能替代 `npm audit` 或第三方安全工具的常规审计;它是一个补充层,无需在每个发布周期都主动付出努力即可缩小攻击面。 ## 工作原理 给定滞后 N 个版本,目标版本为 `versions[latest_index - N]`。只计算稳定版本;预发布版本(可配置,默认排除 `-alpha`、`-beta`、`-rc`、`-next`、`-canary`、`-dev`)。如果一个包的发布版本数少于滞后值,recul 会锁定到最旧的可用稳定版本。 默认情况下,已比滞后目标旧的包不会被处理。不变式是"永不太新",而不是"恰好落后 N 个"。 ## 需求 - Node.js 18 或更高版本 ## 安装 ``` npm i -D @crbroughton/recul # 或者 pnpm add -D @crbroughton/recul ``` ## 快速开始 ``` # 在当前目录创建配置文件 recul init # 审计您的依赖项 recul ``` ## 配置 提交 `recul.config.jsonc` 以在团队中统一设置。 ``` { // How many versions to stay behind the latest published release. // Counted in releases, not semver increments. // // 1 → days to weeks (fast-moving projects, minimal buffer) // 2 → weeks (balanced default, recommended) // 3 → weeks to months (cautious teams, slower release cadences) // 5+ → months (regulated environments, high-security contexts) "lag": 2, // Package manager: "npm" | "pnpm" "packageManager": "pnpm", // Path to the package.json to audit, relative to this config file. "packageFile": "package.json", // How to handle packages already older than the lag target. // "ignore" → treat as ok, no output (default) // "report" → surface them with a safe upgrade-to-target command "behindBehavior": "ignore", // Version prefix used in generated install commands. // "exact" → 1.3.4 (recommended; audits are reliable) // "caret" → ^1.3.4 (allows minor/patch drift) // "tilde" → ~1.3.4 (allows patch drift only) // // Per-package map also supported: // { "default": "exact", "react": "tilde" } "rangeSpecifier": "exact", // Packages to skip entirely. "ignore": [], // Minimum days a version must have been published before it is eligible // as a lag target. Combines with "lag" for defence-in-depth. // Omit or set to 0 to disable. "minimumReleaseAge": 3, // Version strings containing any of these substrings are treated as // pre-releases and excluded from the candidate list. "preReleaseFilter": ["-alpha", "-beta", "-rc", "-next", "-canary", "-dev"], // Restrict the candidate list to the same major as the currently declared version. // Prevents resolving a target across major version lines (e.g. axios 0.x vs 1.x). // Can be a per-package map: { "default": true, "axios": false } "sameMajor": true } ``` 需要配置文件;如果没有,请运行 `recul init`。 ## CLI 参数 | 参数 | 描述 | |------|-------------| | `-f, --file` | `package.json` 的路径(默认:`package.json`)| | `--fix` | 直接将 catalog 修复应用到 `pnpm-workspace.yaml` | | `--behindBehavior=` | 覆盖配置中的 `behindBehavior`(`ignore` 或 `report`)| ## 输出 ``` recul staying 2 versions behind latest settings lag 2 ; stay 2 versions behind latest pm pnpm ; the chosen package manager behind ignore ; ignore packages behind target range exact ; pin exact versions minAge 3 ; skip versions published within the last 3 days package declared → target latest gap status ────────────────────────────────────────────────────────────────────────────────────── express ^4.19.2 4.17.3 4.19.2 2 ↓ will pin back react ^18.3.1 18.1.0 18.3.1 2 ↓ will pin back typescript 5.4.5 5.4.5 5.4.5 0 ✓ ok to pin back: pnpm add express@4.17.3 react@18.1.0 ``` ### 状态值 | 状态 | 含义 | |--------|---------| | `✓ ok` | 处于或滞后于滞后目标 | | `↓ will pin back` | 领先于滞后目标;显示安装命令 | | `↑ safe to upgrade` | 落后于目标(仅在 `behindBehavior: report` 时显示)| | `✗ unresolved` | 注册表获取失败或未找到稳定版本 | 当一个包使用与 `rangeSpecifier` 不同的范围前缀声明时,会附加 `⚠ declared ` 警告;这意味着审计的版本可能与实际安装的版本不同。 ## pnpm catalog 支持 当使用带有 `pnpm-workspace.yaml` 中 `catalogs` 块的 pnpm 工作区时,recul 会读取 catalog 条目以解析 `package.json` 中的 `catalog:` 和 `catalog:` 引用。 Catalog 管理的包中的违规会报告需要更新的 catalog 条目,而不是安装命令。传递 `--fix` 以直接应用到 `pnpm-workspace.yaml`。 ## Lockfile 支持 当存在 lockfile 时,recul 会从中读取已安装的版本并使用它进行比较,而不是声明的范围。这对于使用 `^` 或 `~` 声明的包可以给出准确的结果。 | 包管理器 | Lockfile | |----------------|----------| | npm | `package-lock.json` (v3) | | pnpm | `pnpm-lock.yaml` (v6+) | ## GitHub Actions 将 recul 添加到你的 CI 流水线中,以便在依赖领先于其滞后目标时使工作流失败: ``` - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 - uses: CRBroughton/recul@v1 ``` ### 输入 | 输入 | 默认值 | 描述 | |-------|---------|-------------| | `working-directory` | `.` | 包含 `recul.config.jsonc` 和 `package.json` 的目录 | | `fail-on-violations` | `true` | 设为 `false` 以进行不会失败的信息性运行 | | `behind-behavior` | `` | 覆盖配置中的 `behindBehavior`(`ignore` 或 `report`)| ### 退出码 | 代码 | 含义 | |------|---------| | `0` | 所有包都在其滞后目标范围内 | | `1` | 一个或多个包需要锁定、未解决,或(在 `behindBehavior: report` 时)落后于目标 |
标签:GNU通用公共许可证, MITM代理, Node.js, npm, pnpm, 依赖滞后, 依赖管理, 包管理器, 安全可观测性, 攻击面减少, 数据可视化, 暗色界面, 漏洞防护, 版本控制, 统一API, 自动化攻击, 软件供应链, 防御性安全