关于 basercms-security-advisory
basercms-security-advisory 是用于处理 baserCMS 仓库安全公告的指南与脚本工作流,覆盖核查、修复和本地测试。它聚焦代码验证、按公告创建分支与 PR,以及集成检查,不负责公告沟通或发布。
主要功能
- 01列出并获取安全公告详情
- 02依据当前分支代码核查报告
- 03按公告创建 Fork、分支和 PR
- 04集成修复并运行本地测试
- 05提供发布后与分支维护指引
适用场景
- 01分类处理 baserCMS 仓库安全公告
- 02为不同公告准备独立代码修复和 PR
- 03通过本地测试验证集成后的安全改动
- 04发布后检查修复是否已纳入
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ baserproject/ baser-skills --skill basercms-security-advisory安装后在 Claude Code 中输入/basercms-security-advisory确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
scripts/build-integration.shcommon.shcreate-fork-branch.shfetch-advisory.shlist-advisories.shopen-pr.shpush-with-retry.shrun-tests.sh详细介绍
baserCMS 安全公告处理指南
端到端处理 baserCMS 仓库安全公告(包括 GHSA 和 triage):从列表、验证、按问题修复,到 fork、分支、PR 和本地验证。脚本位于 scripts/ 下。base 分支是运行时的当前分支(请预先 checkout 目标发布分支)。
0. 前提条件
- 已通过
ghCLI 完成身份验证。目标 upstream 为BCSA_UPSTREAM(默认值:baserproject/basercms)。 - 安全公告的私有 fork 不支持 Copilot 审查和 GitHub Actions。审查应使用本地
/code-review,测试应使用本地 Docker(basercms-unittest)。 - fork full_name=
<owner>/basercms-<小写GHSA>,remote=sec-<小写GHSA(去除开头ghsa-)>,分支=security/<GHSA-ID>。
1. 列表和分类
使用 scripts/list-advisories.sh [--state triage] 获取各 state 的数量和列表,并筛选出 triage。
2. 验证报告
使用 scripts/fetch-advisory.sh <GHSA-ID> 获取详细信息,并与当前分支的实际代码进行对照,判断为“准确 / 不准确 / 不适用”。如果目标较多,可由只读并行子 Agent 分工处理。对于利用框架的默认保护(ORM 绑定 / slug 编码 / h() 输出)无法复现的问题,应判定为不适用并驳回,同时要求提供具体 PoC。
3. 确定修复方案
整理同一 sink 的重复公告、共享文件的 hunk 拆分,以及不适用问题的驳回。对于重复问题的处理方式(在多个 fork 中应用相同修复 / 将其中一个重复公告关闭)等需要判断的事项,应向用户确认。
4. 按问题创建 fork、分支和 PR
针对每个公告:
scripts/create-fork-branch.sh <GHSA-ID>— 创建 fork → 添加 remote → 从当前分支创建分支- 仅应用相关 hunk(多个公告涉及同一文件时,不要使用
git checkout … -- file全量取回,而应手动按 hunk 应用) - 提交信息应明确说明修复了哪项漏洞以及如何修复
scripts/push-with-retry.sh <remote> security/<GHSA-ID>— 带重试机制推送,等待 fork 生效scripts/open-pr.sh <GHSA-ID> [--title T] [--body-file F]— 以当前分支为 base 创建 PR
5. 本地验证
scripts/build-integration.sh [集成分支名]— 合并当前分支和所有security/GHSA-*(发生冲突时停止)scripts/run-tests.sh— 在本地运行全部测试(详情见basercms-unittest)- 如有需要,将集成分支推送到个人 fork(
<个人フォーク名>)以运行 GHA(GHA 不会在安全公告 fork 中运行)
6. 跟进最新 base
origin/base 更新后,将 base 合并到各 PR 分支并重新推送。常见冲突:
order() → orderBy()(CakePHP 5.2 更名)- 合并路径验证
realpath() === false绕过修复与$fullPath验证
6b. 发布后确认合入并整理分支
在 GitHub 上合并安全公告 fork 的 PR 后,base 分支中会以 一个名为“Merge commit from fork”的提交(squash) 的形式合入。由于 security/<GHSA-ID> 分支本身不是 base 的祖先,git merge-base --is-ancestor 和 git branch --merged 会显示“未合并”。应通过内容差异确认是否已合入。
- 获取目标分支修改的文件列表,并仅比较这些文件与 base 的差异(差异为零即表示已合入):
对于仍有差异的文件,使用base=$(git merge-base security/<GHSA-ID> origin/5.4.x) files=$(git diff --name-only $base security/<GHSA-ID>) git diff --name-only origin/5.4.x security/<GHSA-ID> -- ${=files} # zsh。bash は $filesgit log <branch>..origin/5.4.x -- <file>确认它们是否只是“合入后又被其他提交修改”。 - 对已确认合入的
security/*,使用git branch -D删除(删除前须获批准。应保留 10/22 等下次发布的分支、面向客户的补丁(consolidated-5.2.x)和未合入的分支)。 - 多个公告修改同一文件时(例如 BlogTags API 的 v9g2 和 636g),较早合并的 fork 提交可能已经包含后续修复。若合并后续 PR 后差异为零,说明该问题在此发布版本中已得到修复。
- 5.3.x → 5.4.x 系列合并时,VERSION.txt 第 1 行、composer.json 和 composer.lock 一定会冲突。版本值应采用较高系列(ours)的版本,并仅将较低系列的发布区块添加到 VERSION.txt 中 5.4.x 区块的下方。
7. 常见陷阱
- 不可使用 Copilot/GHA:在安全公告 fork 中无法使用。应以本地验证为准。
- 等待 push 生效:新建 fork 后立即 push 会出现
remote rejected (failure)。根据退出代码重试(不要因->等字符串而误判为成功)。 - 拆分共享文件的 hunk:例如,
PluginsService的 basename 和 php 执行路径验证属于不同的安全公告。按 hunk 单位拆分后应用。 - 同一 sink 重复处理:将同一修复应用到多个 fork,或重复关闭其中一个。
- 判断是否适用:如果因 framework 默认保护而无法复现,则应驳回。追溯确认报告时的分支状态。
- 完整套件中的不稳定测试:
CreateReleaseCommandTest(实际运行 composer)单独运行时通过。应区分环境因素。 - 授权边界:修改
permission.php中的 Api/Admin 以及 Admin 的auth一致性之前,先确认对管理界面 SPA(包括已构建的 JS)的依赖。 - 稍后发布旧系列版本时,monorepo-builder 会停止运行:
ReleaseGuard只允许发布版本号高于「本地标签中 committer date 最新的标签」的版本(不会按系列分别比较)。如果要在 5.4.0 之后发布 5.3.1,请在发布工作副本中运行git tag -d 5.4.0,然后执行vendor/bin/monorepo-builder release 5.3.1,完成后运行git fetch origin --tags恢复标签。此操作不会影响远程标签。 - prepare release 会包含未跟踪文件:monorepo-builder 的 release 也会提交工作树中的未跟踪文件。如果较低系列(5.3.x)的
.gitignore中没有仅属于较高系列的插件(webroot/bc_burger_editor・webroot/bc_mcp的符号链接),这些文件就会直接进入标签。发布前确认git status --short为空,并确保各系列的.gitignore一致。如果文件被意外包含,可通过git rm --cached和补充.gitignore条目修复。 - Packagist 的更新晚于网页显示:split 工作流成功后,即使 packagist.org 页面上已显示新版本,Composer 读取的
repo.packagist.org/p2/<vendor>/<pkg>.json可能还要几分钟才会更新。Root composer.json requires ... does not match the constraint通常是由此延迟造成的。使用composer show --all <pkg>确认versions,等待几分钟后重试。清除缓存时,应在执行更新的容器内操作,而非在主机上操作。 - 误发布标签时撤回:不仅要从主仓库删除,还要通过
gh api --method DELETE /repos/baserproject/<repo>/git/refs/tags/<ver>从 split 目标仓库的所有仓库(split_monorepo.yml中的列表)删除。Packagist 会在重新抓取后显示「No longer found in upstream」,并自动删除该版本。对于仍留在 5.x 分支中的发布提交(VERSION.txt 第 1 行・composer.json),另行提交将其恢复为X.Y.Z-dev的修改。
8. 辅助脚本列表
| 脚本 | 参数 | 作用 |
|---|---|---|
| list-advisories.sh | [--state S] | 安全公告列表与汇总 |
| fetch-advisory.sh | <GHSA-ID> | 获取单个公告的详细信息(保存到 /tmp/bc-advisories) |
| create-fork-branch.sh | <GHSA-ID> | 创建 fork→remote→以当前分支为起点的分支 |
| push-with-retry.sh | <remote> <branch> [max] | 等待生效并重试 push |
| open-pr.sh | <GHSA-ID> [--title T] [--body-file F] | 以当前分支为 base 创建 PR |
| build-integration.sh | [統合ブランチ名] | 将所有 PR 合并到集成分支 |
| run-tests.sh | [--filter X] | 本地运行所有测试(与 basercms-unittest 联动) |
9. 与现有技能的协作
- 联系、记录和公开内容不属于本技能范围:回复报告者的评论、更新 GHSA 的受理/严重程度/影响和修复版本/credits/重复关闭等元信息、CVE 申请状态、与 JPCERT/JVN 的往来、供应商声明、官方网站漏洞信息页面的文稿、在管理表/任务/聊天中记录,以及发布当天的检查,均按漏洞处理(协调与公关)流程进行。本技能专注于「代码验证、修复、fork/PR、本地验证」,并反馈结论(是否适用、分支名称、PR URL、测试结果)。
- 测试执行:
basercms-unittest - 迁移导致的冲突与弃用:
cakephp-migration/php-migration/basercms-plugin-migration