Skip to content
返回维护与 LTS

安全回移植

把安全修复从当前发布回移植到 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 分支。