mcpField
C
chrome-release-cls

chrome-release-cls

github.com/electron安全123.6k45 次安装今天更新
代码仓库

关于 chrome-release-cls

这项 skill 将 Chrome Releases 博客中的安全修复映射到 Gerrit 变更列表(CL)。它检索代码库历史、Gitiles 和 Gerrit,并处理组件专属来源及受限变更。

主要功能

  1. 01提取 CVE 和 Bug ID
  2. 02搜索本地及远程历史
  3. 03通过 Gitiles 和 Gerrit 查找修复
  4. 04处理组件专属代码库
  5. 05追溯 cherry-pick 对应的主变更
  6. 06按严重级别整理结果

适用场景

  1. 01识别 Chrome 安全发布中的修复
  2. 02查找已报告 Bug 对应的上游 CL
  3. 03追踪 Chromium roll 提交之外的组件修复
  4. 04核查近期或受限的修复

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/electron/electron --skill chrome-release-cls

安装后在 Claude Code 中输入/chrome-release-cls确认已加载。

详细介绍

Chrome 发布 → 查找修复 CL

将 Chrome 发布博客文章中的每项安全修复映射到修复它的 Gerrit CL。

输入

$ARGUMENTS — 一个 https://chromereleases.googleblog.com/... URL。如果为空,请向用户索取一个。

流程

1. 从博客文章中提取 CVE → Bug ID 对

博客 HTML 会将 Bug ID 隐藏在 <a> 标签中,因此请先移除标签。运行:

curl -sL "$URL" | python3 -c '
import sys, re, html
t = re.sub(r"<[^>]+>", " ", sys.stdin.read())
t = re.sub(r"\s+", " ", html.unescape(t))
seen = set()
for m in re.finditer(r"\[\s*(\d{6,})\s*\]\s*(Critical|High|Medium|Low)\s*(CVE-\d{4}-\d+):\s*([^.]+?)\.", t):
    if m.group(3) in seen: continue
    seen.add(m.group(3))
    print(f"{m.group(3)}|{m.group(1)}|{m.group(2)}|{m.group(4).strip()}")
' > /tmp/cve_bugs.txt
cat /tmp/cve_bugs.txt

如果没有结果,说明页面格式可能已更改——请改用 grep -oE 'CVE-[0-9]{4}-[0-9]+' 和 grep -oE 'crbug\.com/[0-9]+',并按顺序配对。

2. 查找每个 Bug 对应的修复 CL

在 Chromium 检出目录和相关子仓库的 Git 历史中搜索提交,其 Bug: 或 Fixed: 页脚引用了该 Bug ID,然后提取 Reviewed-on: Gerrit URL。

按组件关键词选择仓库:

  • ANGLE → third_party/angle
  • Skia、Graphite → third_party/skia
  • PDFium → third_party/pdfium
  • Dawn → third_party/dawn
  • V8、Turbofan、Maglev、Turboshaft → v8
  • 其他所有情况 → .(chromium/src)

如果提示的仓库中没有匹配项,也始终回退到 .。

cd /root/src/electron/src   # chromium root (parent of electron/)

lookup() {
  local bug="$1" repos="$2"
  for repo in $repos . v8 third_party/skia third_party/angle third_party/pdfium third_party/dawn; do
    local hits
    hits=$(git -C "$repo" log --all --since='6 months ago' -E \
           --grep="(Bug|Fixed):.*\\b${bug}\\b" --format='%H' 2>/dev/null | sort -u)
    [[ -z "$hits" ]] && continue
    while read -r h; do
      git -C "$repo" log -1 --format='%B' "$h" | grep '^Reviewed-on:' | sed 's/^/    /'
      echo "      ↳ $(git -C "$repo" log -1 --format='%s' "$h")"
    done <<<"$hits"
    return 0
  done
  echo "    (not found locally)"
}

以 /tmp/cve_bugs.txt 为输入。优先将不带 [M1xx] 前缀的提交主题作为规范的主 CL;带 [M1xx] 的提交是分支挑选提交。

3. 处理未命中

对于本地未找到命中的 bug:

  • 运行 git -C <repo> fetch origin,然后使用 --remotes 重新搜索(修复可能比当前检出版本更新)。
  • 搜索 gitiles 历史记录——无论是否有检出都能使用,也不需要身份验证。查询 refs/heads/main 以及该版本的分支 refs(chromium/src 使用 refs/branch-heads/<Chromium branch number>,v8/v8 使用 refs/branch-heads/<V8 major.minor>;对于 chromium.googlesource.com 上的 angle/angle 和 skia 也采用同样方式,以及 pdfium.googlesource.com/pdfium、dawn.googlesource.com/dawn、aomedia.googlesource.com/aom)。响应以一行 )]}' 开头;gitiles grep 会在整条提交消息中进行子串匹配,因此请检查命中项的 Bug:/Fixed: 页脚:
    gitiles_grep() {  # gitiles_grep <host> <repo> <ref> <bug>   e.g. chromium v8/v8 refs/branch-heads/15.2 558734727
      curl -s "https://$1.googlesource.com/$2/+log/$3?format=JSON&n=50&grep=$4" | tail -n +2 | python3 -c '
    import sys, json, re
    for c in json.load(sys.stdin).get("log", []):
        if re.search(r"^(Bug|Fixed):.*\b" + sys.argv[1] + r"\b", c["message"], re.M):
            print(c["commit"], c["message"].splitlines()[0])
    ' "$4"
    }
    
    对于 chromium/src,务必使用范围限制遍历——对其完整历史执行无限制 grep 会超时(HTTP 502):将 refs/branch-heads/<previous milestone's branch>..refs/branch-heads/<this branch> 和 refs/branch-heads/<this branch>..refs/heads/main 作为 ref 传入(分支编号是 Chrome 版本号的第三部分,例如 153.0.8010.x 对应 8010;前一个里程碑的分支编号可在 https://chromiumdash.appspot.com/fetch_milestones?mstone=<N-1> 中查询)。子仓库规模较小,可以不受限地遍历(只需几秒)。命中结果会给出 sha、ref 和(从提交消息中获取的)Reviewed-on: CL——即使 Gerrit 拒绝显示该 CL,也应将其报告为修复。
  • 直接查询 Gerrit:curl -s "https://chromium-review.googlesource.com/changes/?q=bug:${BUG}&n=10" | tail -n +2 | python3 -m json.tool(也尝试 skia-review、pdfium-review、dawn-review、aomedia-review)。
  • **b/ bug 格式(Skia、Graphite、Dawn):**这些仓库在提交消息中使用 b/<id> 引用 bug,而不是使用 Bug: <id> 页脚。Gerrit 的 bug: 查询不会返回任何结果。请改用 message:<id> 搜索:
    curl -s "https://skia-review.googlesource.com/changes/?q=message:${BUG}&n=5" | tail -n +2
    
    如果组件是 Dawn,也对 dawn-review.googlesource.com 使用相同模式。
  • **从合并提交追溯主分支 CL:**如果只找到 [M1xx] 合并 CL,请查询 CL 详情中的 cherry_pick_of_change,以找到原始主分支 CL 编号:
    curl -s "https://chromium-review.googlesource.com/changes/${CL_NUM}?o=CURRENT_REVISION" | tail -n +2 | python3 -c "
    import sys, json
    d = json.load(sys.stdin)
    print(d.get('cherry_pick_of_change', 'none'))
    "
    
  • **在 Gerrit 中受限的 CL 仍可能在 git 中公开。**变更记录和仓库使用不同的 ACL,且变更通常会在提交进入 main 和 branch-heads 后数天内仍处于隐藏状态。因此,只有在 git 历史记录(本地记录以及 fetch 后的 --remotes)和 gitiles 中都没有结果时,才能判定为 RESTRICTED——仅 Gerrit 未命中并不足够。
  • 如果仍未找到结果,且 bug 是最近才报告的(尤其是由“Google Threat Intelligence”报告或标记为在野利用),则该 CL 可能仍受访问限制——应报告为 RESTRICTED,而不是猜测,并标记以便重新检查(限制通常会在数小时内解除)。
4. 特殊情况
  • **Roll CL——跳过并查找上游修复:**对于修复会落在上游仓库的组件(PDFium、Dawn、Skia、Graphite、libaom、libvpx、ffmpeg),chromium-review 中的命中会是 Roll src/third_party/... 提交。不要将 roll CL 报告为修复,而应直接查询组件自己的 Gerrit 实例,查找实际修复 CL:

    • PDFium → pdfium-review.googlesource.com(使用 bug: 或 message: 查询)
    • Dawn → dawn-review.googlesource.com(使用 message: 查询——采用 b/ 格式)
    • Skia / Graphite → skia-review.googlesource.com(使用 message: 查询——采用 b/ 格式)
    • libaom → aomedia-review.googlesource.com

    只有在上游 Gerrit 实例没有返回结果时,才应退而报告 roll CL——此时请附上 roll CL,并注明实际修复位于上游,但无法确定具体 CL。

  • 同一提交正文中有多行 Reviewed-on::cherry-pick 会保留原始行并新增一行。第一行 Reviewed-on: 是原始 CL。

  • 一个 bug 可能有多个不同的修复 CL(修复 + 后续加固)——请全部列出。

5. 输出

按严重级别分别生成 Markdown 表格:CVE | Bug | Component | Fix CL (main)。将 Bug 链接到 https://crbug.com/<id>。将原始输出(包括所有分支合并)保存到 /tmp/cve_cls.txt,并注明该路径。

评论

支持 Markdown