安全回移植
把安全修复从当前发布回移植到 LTS 版本,使留 LTS 不意味脆弱。
为什么
LTS 用户若无安全修复是被攻破的 LTS 用户 — LTS 承诺是"你可留此版本且保安全",回移植是守此承诺的方式。回移植取 v20 的修复并适配到 v18 的代码库(可能不同文件结构、API、依赖)。纪律是仅回移植安全 + 关键修复(非功能、非装饰 bug)、在 LTS 分支测每个回移植、作为补丁(v18.20.1)发布带命名 CVE 的 changelog。无回移植则 LTS 是谎 — 标"支持"却实对当前修的每 CVE 脆弱的版本。
何时使用
当前每安全修复回移植到所有活跃 LTS 版本。自动化回移植 PR 创建。
如何做
1. 当前(v20)落安全修复时,识别所有活跃 LTS 分支(v18、v16) 2. 用回移植 bot(如 backport-action)或 cherry-pick:git cherry-pick <修复提交> 到 LTS 分支 3. 解冲突(修复可能触及 LTS 中不同代码)— 适配非盲拷 4. 跑 LTS 分支测试套件;若无则加 CVE 回归测试 5. 作为补丁发:v18.20.1,changelog "安全:从 v20 回移植 CVE-2024-1234 修复" 6. 通过 LTS 发布渠道(与当前 changelog 分开)通知 LTS 用户 7. 跟踪回移植仪表盘:CVE、当前修、回移植到 [v18, v16]、每分支状态
示例
# 从 v20 回移植安全修复到 v18
# 1. main(v20)上的修复提交
git log --oneline # abc1234 fix: CVE-2024-1234 merge() 原型污染
# 2. cherry-pick 到 LTS 分支
git checkout lts/v18
git cherry-pick abc1234
# src/merge.ts 冲突(v18 中文件不同)— 解:
# 把修复适配到 v18 的 merge() 签名,别拷 v20 版本
# 3. 在 LTS 分支测
npm ci && npm test # 须过;加 CVE 回归测试
# test/cve-2024-1234.test.ts:
it('对 CVE-2024-1234 不脆弱', () => {
expect(() => merge({}, JSON.parse('{"__proto__":{"polluted":1}}'))).not.toThrow();
expect({}.polluted).toBeUndefined();
});
# 4. 作为补丁发
git tag v18.20.1
# changelog:"v18.20.1 (LTS):安全 — 从 v20.20.0 回移植 CVE-2024-1234 修复"
# 回移植仪表盘
| CVE | 修于 | 回移植到 | 状态 |
|----------------|----------|--------------------|--------|
| CVE-2024-1234 | v20.20.0 | v18.20.1, v16.20.5 | 完成 |
| CVE-2024-5678 | v20.20.1 | v18(进行中) | wip |常见问题
- ⚠盲 cherry-pick 不适配 LTS 代码库 — 修复引用 v18 不存在的函数,构建坏。
- ⚠安全修复连功能一起回移植 — LTS API 变了,坏为稳选 LTS 的用户。
- ⚠回移植 CVE 无回归测试 — 修复在但未来重构悄悄回退因无物抓。
最佳实践
- ✓仅回移植安全 + 关键修复到 LTS,绝不功能 — LTS 用户选稳,API 变破此承诺。
- ✓每回移植 CVE 在 LTS 分支加回归测试 — 测试证修复且防静默回退。
- ✓自动化回移植 PR 创建(backport-action)使 main 上修复数分钟内开 PR 到所有活跃 LTS 分支。