跳至内容

安全告警与网页发布维护

教材页面已经能打开,但仓库仍然会收到 Dependabot 告警、Actions 弃用提示和分支保护问题。源码学习仓库也要维护,否则新手看到的页面和仓库实际状态会逐渐分离。

先分清三类事情

事情主要证据能证明什么
依赖漏洞GitHub Dependabot 告警、锁文件、可升级版本某个依赖版本落在漏洞范围内,或 GitHub 认为存在风险
网页发布Pages workflow、docs:build、线上 URL页面可以从指定提交构建并访问
运行时安全宿主、插件、Hook、注入器的实际安装和运行某个方案在指定平台和版本上的真实行为

不要把第一行的“依赖告警已读取”写成“漏洞已经修复”,也不要把第三行的静态检查写成“插件安全”。每一类结论都要用对应证据回答。

本仓库的维护快照

下面是 2026-08-16 对公开学习仓库的审计记录。它是一个可复查的快照,不是永久不变的状态。

  • GitHub Dependabot 当前报告 47 条未关闭告警:12 条 high、30 条 medium、5 条 low。
  • 告警主要涉及 mermaidviteundicihonoip-addressfast-uribrace-expansionjs-yamlpostcssdompurifyprotobufjs 等依赖。
  • master 分支保护当前禁止 force push,也禁止删除分支;required status checks 没有被强制设为合并前置条件。
  • 工作流显式使用 Node 24;仓库当前没有把 Node 20 写成主构建版本。GitHub Actions 对第三方 action 或平台运行时给出的弃用提示,仍需逐条检查来源,不能看到“Node.js 20”就把它归因于项目代码。

这些结论来自 GitHub 仓库设置、Dependabot API、工作流文件和本地文档构建。它们没有证明真实 DSH、provider、模型或社区插件的运行安全。

2026-08-17 的 GitHub API 复核

本次使用已登录的 gh api 只读获取 repos/shine-233/deepseek-harness-study/dependabot/alerts?state=open&per-page=100,得到 47 条未关闭告警:12 high、30 medium、5 low。不带 state 过滤时共返回 51 条,其中 4 条为 auto_dismissed。按依赖范围分组,30 条是 development、17 条是 runtime。出现次数最多的包是 mermaid 15 条、vite 6 条、undici 5 条、hono 4 条、brace-expansionip-address 各 3 条。当前 API 返回了多个 first_patched_version:例如 fast-uri 的 3.1.4/3.1.5、ip-address 的 10.3.1、js-yaml 的 4.3.0/4.3.1、undici 的 7.29.0 和 vite 的 6.4.2/6.4.3。它们只表示 advisory 提供了候选修复版本,不能替代逐条兼容性、构建和 Pages 回归测试。

同一次读取显示:Secret scanning 和 Secret scanning push protection 是 enabled,Dependabot security updates 是 disabled。Code Scanning alerts 接口返回 no analysis found,因此不能把它写成“代码扫描通过”。master 分支保护返回 allow_force_pushes=falseallow_deletions=false、required status checks 为 null;Pages 返回 workflow 发布、源分支 master、路径 / 和 HTTPS enforced。最近一次远端 Pages run(run 31941869420)成功,但这只证明那次构建部署成功。

远端最近一次 Pages 日志还明确给出:主工作流使用 Node 24,但 pnpm/action-setup@v4 的 action runtime 目标仍是 Node 20,GitHub 将它强制运行在 Node 24 并发出弃用警告。这个警告来自 action runtime,不是项目脚本把 node-version 写成了 20。当前工作树已把工作流 action 版本更新到较新的组合,但本次没有执行发布;发布后仍要重新查看 Actions 日志,确认 warning 是否消失。

2026-08-17 本机 pnpm audit 复核

本机先按项目默认 registry 运行 pnpm audit --json,得到的是 ERR_PNPM_AUDIT_ENDPOINT_NOT_EXISTS;这只说明当前镜像没有提供 audit endpoint。随后在不改配置、不写锁文件的前提下,临时指定官方 npm registry 重新读取 advisory:依赖树共 1,204 个节点,返回 33 个 advisory,严重度为 high 15、moderate 16、low 2、critical 0。涉及的代表性模块包括 viteesbuildpostcsshonoundicifast-urijs-yamlbrace-expansionnanoidprotobufjsdompurifyip-address

这个数字不能直接替换前面的 GitHub Dependabot 47 条开放告警:两者读取时点、锁文件投影、重复路径和 advisory 聚合方式不同。它也不等于“33 个漏洞都能在当前项目中被利用”,更不等于“已经修复”。下一步应按直接依赖、传递依赖、运行时依赖和仅开发期依赖分批升级,每批都重跑源码构建、单元测试、lint、Pages 构建和行为门禁,再回到 GitHub 查看告警是否真正关闭。

第一步:读取告警,不要马上全量升级

在有权限的 GitHub 环境里,可以先读取告警摘要:

powershell
$alerts = gh api --paginate `
  'repos/shine-233/deepseek-harness-study/dependabot/alerts?state=open&per-page=100' |
  ConvertFrom-Json
$alerts.Count
$alerts | Group-Object { $_.security_vulnerability.severity }

再看每条告警的依赖路径、当前版本范围、修复版本和 advisory:

powershell
$alerts | ForEach-Object {
  [pscustomobject]@{
    Package = $_.dependency.package.name
    Manifest = $_.dependency.manifest_path
    Scope = $_.dependency.scope
    Severity = $_.security_vulnerability.severity
    VulnerableRange = $_.security_vulnerability.vulnerable_version_range
    Patched = $_.security_advisory.first_patched_version.identifier
    Advisory = $_.security_advisory.ghsa_id
  }
}

看到 47 条并不代表要手工改 47 次。一个传递依赖可能对应多条 advisory;同一个 mermaidvite 也可能同时出现在根工作区和 website/ 的依赖图中。先按“直接依赖、传递依赖、运行时依赖、开发依赖”分组,再决定升级范围。

第二步:用小批次升级和门禁确认

建议的顺序是:先升级明确有修复版本的直接依赖,再让 pnpm 重算锁文件,最后逐层运行检查。

powershell
pnpm install --lockfile-only
pnpm run build
pnpm run docs:check
pnpm run doc-sync
git diff --check

如果本地 registry 返回“audit endpoint 不存在”,这只说明当前镜像没有提供 pnpm audit 接口,不说明仓库没有漏洞。此时以 GitHub Dependabot advisory 为漏洞记录来源;更换 registry 或升级依赖必须由维护者明确选择,不能为了让命令变绿而删除锁文件、关闭告警或加无依据的忽略规则。

每个升级批次至少要记录:升级前后的直接依赖、锁文件变化、构建结果、网页构建结果、告警数量变化,以及仍然没有修复版本的 advisory。只有 GitHub 告警关闭并且相关构建与行为检查通过,才能把某一批写成“已处理”。

第三步:理解 Node.js 20 弃用提示

Actions 的 Node.js 20 提示可能来自三处:

  1. 工作流自己写了 node-version: 20
  2. 某个 action 的运行时仍由 GitHub 平台托管在 Node 20;
  3. action 或构建脚本启动了另一个 Node 20 子进程。

先搜索工作流和 action 版本:

powershell
rg -n -i 'node-version|node20|node.js 20|actions/' .github

然后在对应的 Actions run 页面查看 warning 的 action 名称。把工作流主 Node 升到 24,不能自动修复一个内部仍声明 Node 20 的第三方 action;应升级该 action 到兼容版本,或者等待 action 维护者发布迁移。升级后要确认 Pages artifact、study-quality 和本地 pnpm run docs:check 都仍然通过。

第四步:把网页“读完”变成可检查的条件

本教材的网页完成条件不是“根页返回 200”这一条:

  • 根路径进入学习入口,首页能把完全新手分流到第一课、任务单、索引和实验课。
  • START-HERE.mdstudy/**/*.md 的每个 Markdown 来源都对应一个 Pages 路由,路由不能重复。
  • 左侧课程树包含学习路线和折叠的逐文件索引;正文页提供搜索、本页目录和上一篇/下一篇导航。
  • docs:check 同时检查投影映射、站内链接、片段和 VitePress 构建。
  • 页面可读不等于源码结论已运行;每个课的“源码证据”和“未验证范围”仍要保留。

因此,网页端可以完整阅读整套教材;真正需要终端的只是构建、测试、性能实验和真实 DSH 运行。网页首页不应强迫读者先创建 Codespace。

最后检查清单

  • [ ] 我能说出告警数量、告警关闭和漏洞修复不是同一个状态。
  • [ ] 我先区分直接依赖和传递依赖,再决定升级范围。
  • [ ] 我知道 pnpm audit 的镜像错误不能被解释为“没有漏洞”。
  • [ ] 我能从工作流文件和 Actions warning 判断 Node 20 提示的来源。
  • [ ] 我能用 docs:check 证明教材路由和构建输入完整,但不会把它写成 DSH 运行安全证明。

下一步可以回到后续研究路线,把依赖维护、工具可见性实测、Hook bridge 审核和真实 Loader 运行分别排队;不要把它们混成一个“CI 通过所以全部完成”的结论。