Skip to content

fix(security): 核销 13 条 Dependabot 告警——next 16.3.5 + js-yaml 4.3.2,并厘清扫描分支错位 - #1143

Merged
ThreeFish-AI merged 4 commits into
feature/1.x.xfrom
ThreeFish-AI/beirut-v3
Sep 14, 2026
Merged

ThreeFish-AI merged 4 commits into
feature/1.x.xfrom
ThreeFish-AI/beirut-v3

Conversation

@ThreeFish-AI

Copy link
Copy Markdown
Owner

背景

告警清单与定性

告警号 严重度 现状取证 本 PR 处置
708–711 next 16.2.12 critical ×4 ui / wiki 两侧 master 与 1.x.x 同为 16.2.12,真实受影响 升至 16.3.5 ✅
699–707 js-yaml 4.3.1 high ×9 11 份视频工程 lock 全为 4.3.1(经 cosmiconfig@8.3.6 传递),真实受影响 地板抬至 ≥4.3.2 ✅
694–698 next ×4 / vitest ×1 critical ×4 + medium apps/cognizes* 已于 2817db6a#1132)删除,仅 master 未同步 留档,等合并自动消解
693 accelerate ≤1.14.0 medium master 为 1.13.0;1.x.x 已随 #1131 升到 1.15.0,超出受影响区间 留档,等合并自动消解

本 PR 消除 13 条;余 6 条在 1.x.x 上早已修好,待特性列车例行并入 master 后自动关闭——不是漏修。 这 6 条刻意不 dismiss:它们挂 open 是「master 落后」这一真实信号的投影,dismiss 只会抹掉信号。dismiss 的适用面是「不能修」,不是「已修但未发布」。

核心变更

1. next 16.2.12 → 16.3.5(消 4 条 critical)

两条均为未认证 RCE:GHSA-p293-qw3h-jr36(CVSS 9.0,Windows 宿主)与 GHSA-2xp9-vwfh-vxw4(Image Optimization API 的 AVIF 路径)。

为何不是最低修复版 16.3.3:16.2 线到 16.2.12 为止、无回溯补丁,升 16.3.x 是唯一路径;而 16.3.3 是以停用 AVIF 图像优化换来的修复,16.3.4 才把 AVIF 正确恢复——停在 16.3.3 等于用功能退化换安全。16.3.5 为该线最新补丁。

2. js-yaml≥4.3.2(消 9 条 high + 一处未告警的同区间隐患)

GHSA-2883-xcg3-v3hh(CVSS 7.5):maxTotalMergeKeys 对空 merge 源不限流致 CPU 耗尽。

  • 11 个 Remotion 视频工程:在 video/pnpm-workspace.yaml 写 override 地板后重锁。该文件属 skeleton.tomlfrozen 档,11 份追加内容逐字节相同。模板与 Dependabot 尚未扫到的两集(context-layer / horizon-context)一并升级——模板不升会让日后 scaffold 出的新集从第一天起就带旧漏洞。
  • 仓库根(未告警,主动消因):根 lock 原解到 js-yaml@4.2.0,同样落在 >=4.0.0 <4.3.2 区间内,地板由 >=4.2.0 抬至 >=4.3.2

踩坑并已修正:首次只写 js-yaml: '>=4.3.2',pnpm 当场解到 5.4.2latest dist-tag),而消费方 @eslint/eslintrc 声明的是 ^4.1.0。补 <5.0.0 后才落到 4.3.2。安全地板 override 一律写闭区间——仓库里 @babel/core / undici 早有同款处置,本次只是补齐到 js-yaml。

3. 随升级必需的两处适配(均非本仓代码缺陷)

  1. @next/eslint-plugin-next@16.3.x 新增规则 no-location-assign-relative-destination(已核对 16.2.12 包内无此规则文件),命中 AuthProviderlogin / logout。二者都是必须的整页跳转——/api/auth/login 是 302 到外部 IdP 的 Route Handler,router.push() 无法承接跨源跳转;登出须整页重载以丢弃客户端状态。故加带理由的定向豁免,不改动认证行为。ui 的 lint--max-warnings=0,新规则的 warning 会直接让 job 红。
  2. 16.3 的 next build 扩大了构建期类型检查范围,暴露 WikiToc.test.tsx 一条已失效的 @ts-expect-errorTS2578)。该错误在基线上跑裸 tsc 同样报,但 16.2.12 的 next build 不报——属被暴露的存量债,非被引入的缺陷。

风险与回滚

  • 主要风险next 16.2 → 16.3 是 minor 升级。16.3.0 变更集经核为 turbopack 内部优化与缺陷修复,无破坏性 API 变更;React 侧版本不动(ui 钉 19.2.3、wiki 用 ^19.0.0,peer 区间不变)。锁文件位移面收敛在 next / eslint-config-next / js-yaml / sharp(next 自带)/ semver 五项。
  • 次要风险:10 个已发布集的视频工程锁文件被刷新。js-yaml 是 cosmiconfig 的传递依赖(配置文件解析),不进渲染链路;package.json 一行未动,structured 档零漂移。
  • 回滚方式:三个提交彼此独立且各自自洽(每个提交的 pnpm-workspace.yaml 与对应 lockfile 始终匹配,不会出现 ERR_PNPM_LOCKFILE_CONFIG_MISMATCH),可按需 revert 单个提交。

验证证据

  • 单元测试:ui pnpm test123 文件 / 1015 用例全通过;wiki pnpm test14 文件 / 122 用例全通过
  • 集成测试:influence 管线 pytest288 passed, 1 failed。唯一失败项 test_source_ledger.py::test_real_map_derives_ep1_urls_byte_identical(断言 len(ledger) == 12 实得 18)已在基线 worktree(a14106cd)逐字复现,与本次变更零交集(本 PR 未触及 sources.toml / source_ledger.py)。
  • E2E/Workflow:ui Playwright smoke → 70 passed, 1 skipped;ui lint / typecheck / typecheck:test / build 全绿;wiki lint / build(含 pagefind 索引)全绿。
  • 专项门禁verify_skeleton.py --strict → 退出 0、未登记漂移 0 处(frozen 档 11 份 video/pnpm-workspace.yaml md5 仍逐字节一致)。
  • 防数据破坏检查:11 次嵌套 pnpm install --lockfile-only 每次之后比对仓库根 pnpm-lock.yaml 的 md5,全程零变更(ISSUE-175 第 ④ 坑:嵌套安装会静默覆写根 lockfile 并丢失全部 overrides,故障延后到 docker build 才现形)。根 lock 的 16 条 overrides 与 4 个 importer 完好,未退化成「只含嵌套工程」的 lock。

影响范围

  • 前端negentropy-ui / negentropy-wikinexteslint-config-next 升版;AuthProvider.tsx 加两条 lint 豁免注释(行为不变);WikiToc.test.tsx 去掉一条失效的 ts 指令。
  • 后端:无。
  • GitHub Actions / 文档:workflow 零改动。docs/.agents/issue.md 的 ISSUE-092 追加 2026-09-14 轮次。11 个视频工程的 pnpm-workspace.yaml / pnpm-lock.yaml(含模板)。

Next Best Action

  1. 合并后仍有 6 条 open 是预期状态,无需再排查——它们会在 feature/1.x.x 下次并入 master 时自动关闭。若希望面板立刻清零,需要的是一次发布列车同步(feature/1.x.xmaster),那是发布节奏决策,未在本 PR 内代为执行。
  2. 本仓至今没有 .github/dependabot.yml,每轮告警都靠人工核销,且「master 落后」会持续制造幻象告警。可考虑新增该配置开启自动升级 PR,并把扫描口径与特性列车分支对齐。
  3. test_source_ledger.py 的存量失败(ledger 18 vs 断言 12)建议单开 PR 处理——它已红在基线上,与安全升级正交。

🤖 Generated with Claude Code

ui / wiki 的 next 停在 16.2.12,命中两条未认证 RCE:GHSA-p293-qw3h-jr36
(CVSS 9.0,Windows 宿主)与 GHSA-2xp9-vwfh-vxw4(Image Optimization API 的
AVIF 路径)。16.2 线无回溯补丁,升 16.3.x 是唯一路径;目标取 16.3.5 而非最低
修复版 16.3.3——16.3.3 是以停用 AVIF 图像优化换来的修复,16.3.4 才把 AVIF
正确恢复,停在 16.3.3 等于用功能退化换安全。

同时把根 workspace 的 js-yaml 地板由 >=4.2.0 抬至 >=4.3.2(GHSA-2883-xcg3-v3hh,
空 merge 源致 CPU 耗尽;根 lock 原解到 4.2.0,落在受影响区间但尚未被 Dependabot
标出)。地板须写闭区间:首次只写 >=4.3.2 时 pnpm 当场解到 5.4.2,而消费方
@eslint/eslintrc 声明的是 ^4.1.0——同 @babel/core / undici 的既有处置补齐 <5.0.0。

随附两处升级暴露的门禁回归(均非本仓代码缺陷):
- @next/eslint-plugin-next 16.3.x 新增 no-location-assign-relative-destination
  规则,命中 AuthProvider 的 login / logout。二者都是必须的整页跳转——
  /api/auth/login 是 302 到外部 IdP 的 Route Handler,router.push() 无法承接
  跨源跳转;登出须整页重载以丢弃客户端状态。故加带理由的定向豁免,不改认证行为。
- 16.3 的 next build 扩大了构建期类型检查范围,暴露 WikiToc.test.tsx 一条已失效
  的 @ts-expect-error(TS2578)。该错误在基线上跑裸 tsc 同样报,属被暴露的存量债。

验证:ui lint / typecheck / typecheck:test / test(123 文件 1015 用例)/ build /
test:e2e(70 passed 1 skipped)全绿;wiki lint / test(14 文件 122 用例)/ build 全绿。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
GHSA-2883-xcg3-v3hh(CVSS 7.5):js-yaml < 4.3.2 的 maxTotalMergeKeys 对空
merge 源不限流,致 CPU 耗尽。各 Remotion 视频工程经 cosmiconfig@8.3.6 传递
引入 4.3.1,直接依赖零位移,故只落在 override 层,package.json 一行不动。

video/pnpm-workspace.yaml 属 skeleton.toml 的 frozen 档(逐字节相同),11 份
追加内容完全一致,verify_skeleton.py --strict 保持「未登记漂移 0 处」。模板
与 10 个已发布集同步升级:模板不升会让日后 scaffold 出的新集从第一天起就带着
旧漏洞,且 Dependabot 尚未扫到的两集(context-layer / horizon-context)也一并
消因,避免 master 同步后再冒出两条新告警。

重锁经 pnpm install --lockfile-only 逐工程执行,每次之后比对仓库根
pnpm-lock.yaml 的 md5,全程零变更(ISSUE-175 第 ④ 坑:嵌套安装会静默覆写根
lockfile 并丢失全部 overrides)。模板目录只有 package.json.tmpl 没有
package.json,pnpm 会以「Scope: all 0 workspace projects」静默空跑,须临时渲染
出 package.json 重锁后再删除。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
本轮 19 条 open 告警里有 6 条在 feature/1.x.x 上早已不存在(cognizes 双项目
随 #1132 整体删除、accelerate 随 #1131 升到 1.15.0 超出受影响区间),仍挂 open
只因 Dependabot 只扫默认分支 master,而 master 停在 2026-09-06、落后 15 个提交。
这条前提此前从未被记录,会让接手者对着已修好的东西反复「修」。

一并留档:13 条真实受影响告警的消除路径与版本取舍依据;这 6 条刻意不 dismiss
的理由(dismiss 的适用面是「不能修」,不是「已修但未发布」);安全地板 override
须写闭区间的教训;以及区分「升级引入」与「升级暴露」的取证方法——用
git worktree add --detach 出基线树分别跑 tsc 与 build 对照。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
@ThreeFish-AI
ThreeFish-AI merged commit 801136a into feature/1.x.x Sep 14, 2026
11 checks passed
@ThreeFish-AI
ThreeFish-AI deleted the ThreeFish-AI/beirut-v3 branch September 18, 2026 02:41
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.

1 participant