找漏洞变便宜之后,补丁窗口、依赖升级节奏、报告质量这三件事的默认假设都要重算。
本站安全格子此前讲的都是防自己被打:Day 24 防注入,Day 50 建护栏。这一期讲另一侧——攻防能力本身在变。2026 年 2 月 Anthropic 披露 Claude Opus 4.6 在开源库里找出并验证了 500+ 个未知高危漏洞;3 月与 Mozilla 合作,两周在 Firefox 里找到 22 个漏洞。8 月 10 日 OpenAI 发布专为网安工作流训练的 GPT-5.6-Cyber,只经 Daybreak Red 准入发放;9 月 2 日 Google 跟进 Gemini 3.8 Flash Cyber,同样只发给 Fairwind 计划的审核通过者。三家走到了同一个形态:能力分档,准入即控制面。对超级个体,这不是"要不要申请 Red"的问题,而是你的依赖树、升级节奏和补丁窗口,都建立在"找漏洞很贵"这个已经失效的前提上。
GPT-5.6-Cyber 把"愿意做"从 1.5% 拉到 95%,却在自家的"找漏洞 + 写报告"评测上输给了通用版。
OpenAI 用内部指标 Advanced Cybersecurity Completion Rate 衡量模型在利用链开发、认证绕过、提权这类请求上的完成率:标准防护下的 GPT-5.6 Sol 为 1.5%,经 Daybreak Blue 放宽后为 2.0%,前代 GPT-5.5-Cyber 为 57.3%,GPT-5.6-Cyber 为 95.0%。注意这个指标量的是意愿,不是准确率。同一份发布里,GPT-5.6-Cyber 在内部 Vulnerability Discovery and Report Writing 评测(找到可利用的严重漏洞、写出能跑的 PoC、提交高质量报告)上反而不如 Sol,官方给的原因是它"有时产出更短、更不详细的漏洞报告"。
工程含义:意愿和能力是两根独立的轴。专用微调在意愿轴上大幅前进,却在"写得完整"这根轴上倒退了。这是微调的老规律:你调的分布之外,总有东西被挤掉。选模型前先判断你的任务卡在拒答还是卡在能力:审自己的仓库、查依赖、读 diff 找注入点,通用模型在授权语境下基本不拒;只有写利用链、做绕过验证这类活才会撞到 1.5% 那面墙。
# 通用模型做防御审计:把授权范围、输出契约、置信度写死
你在审计我本人拥有的仓库 ./src(授权范围:仅此目录,不联网)。
任务:找出可被外部输入触达的内存安全 / 注入 / 认证缺陷。
对每个发现输出 JSON:
{"file":..., "line":..., "class":"CWE-xxx",
"reachability":"外部输入如何到达这里,逐跳列出调用链",
"repro":"最小复现输入或测试用例(必须给出,给不出则 confidence ≤ 0.3)",
"confidence":0.0-1.0, "fix":"最小补丁"}
宁缺毋滥:没有可复现路径的猜测,放进单独的 "hypotheses" 数组,不进 findings。
3 月 Anthropic 说发现比利用便宜一个数量级、但这个差距不会持续太久;8 月就有模型把两个 V8 漏洞串成了沙箱逃逸。
Firefox 合作的数字值得细看:Opus 4.6 两周扫了约 6,000 个 C++ 文件,提交 112 份报告,Mozilla 认定 22 个漏洞、其中 14 个高危,在 Firefox 148 中修复。但团队花了约 4,000 美元 API 额度尝试写 PoC 利用,几百次尝试只成功两次。Anthropic 的结论是"找漏洞的成本比写利用低一个数量级",并补了一句:照进展速度,这个差距不太可能长久。
五个月后,OpenAI 用 GPT-5.6-Cyber 研究 V8,找到两个可以串联的未知漏洞:优化编译器在把值转成整数时跳过了一个安全检查,undefined 会变成一个意外的大数,再被当作数组下标,编译器以为它在界内而省掉边界检查,于是可以越界读写;第二个漏洞用来逃出 V8 堆沙箱。前者被分配为 CVE-2026-15903(CVSS 8.8,Chrome 150.0.7871.128 修复)。对防守方,这意味着"公开修复 → 有人写出利用"的时间在缩短,你的补丁延迟(patch lag)成了主要风险:浏览器自动更新还好,但捆绑 Chromium 的 Electron 应用、钉死版本的容器镜像、半年没动的 lockfile,都在这个窗口里裸奔。
# 量出你自己的补丁延迟:哪些已知漏洞有修复版本、公告挂了多少天你还没升
osv-scanner scan source -r . --format json 2>/dev/null \
| jq -r '.results[].packages[] | .package as $p | .vulnerabilities[]
| [ $p.name, $p.version, .id,
([.affected[]?.ranges[]?.events[]?.fixed // empty] | first // "no-fix"),
(((now - (.published | sub("\\.[0-9]+"; "") | fromdateiso8601)) / 86400) | floor) ]
| @tsv' \
| sort -t$'\t' -k5,5nr | column -t
# 第 4 列有版本号、第 5 列天数大 = 优先处理;"no-fix" 单独列出看是否需要替换依赖
published 是公告日期而非修复日期,严格的延迟指标需要再对上修复版本的发布时间。"快升"防的是已知漏洞,"慢升"防的是投毒包;两个诉求不冲突,只要别用同一条规则管。
漏洞发现变便宜带来两股相反的压力。一边是 CVE 变多、利用变快,要求更快升级;另一边是供应链投毒——恶意版本往往在发布后不久被研究者和自动扫描识破,要求新版本先放一放。很多团队的做法是一刀切地"每周一统一升级",结果两头都没照顾到。
正确的做法是拆车道,而主流工具已经内置了这个区分。Renovate 的 minimumReleaseAge 让每个新版本等满指定时长才提 PR,文档明确写着安全更新绕过所有 minimumReleaseAge 检查;vulnerabilityAlerts 生成的 PR 还会无视 schedule 和按小时的限流,直接插队。Dependabot 的 cooldown 选项同理:只作用于版本更新,不作用于安全更新。
// renovate.json:常规更新冷却 7 天、major 冷却 14 天;安全修复自带快车道
{
"extends": ["config:recommended"],
"minimumReleaseAge": "7 days",
"internalChecksFilter": "strict",
"packageRules": [
{ "matchUpdateTypes": ["major"], "minimumReleaseAge": "14 days" }
],
"vulnerabilityAlerts": { "labels": ["security"], "prConcurrentLimit": 5 },
"osvVulnerabilityAlerts": true
}
# .github/dependabot.yml:等价写法(cooldown 不影响 security updates)
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule: { interval: "daily" }
cooldown:
default-days: 7
semver-major-days: 14
发现便宜了,验证没有便宜:一份没有复现路径的 AI 报告,是把成本转嫁给维护者。
同一年里有两个对照鲜明的数据点。curl 在 2026 年 1 月 31 日关闭了 HackerOne 漏洞赏金,Daniel Stenberg 的理由是低质量、疑似 AI 生成的报告太多,2025 年的提交里只有约 5% 是真漏洞。另一边,Anthropic 的 500+ 个漏洞每一个都由团队成员或外部研究者验证过;即便如此,Firefox 那次 112 份报告对应 22 个确认漏洞。前沿实验室的流水线尚且需要大量人工分诊,个人跑一遍模型就提交,噪声只会更大。
对超级个体,这条线有两头。作为报告者:用 AI 扫别人的代码,"能复现"是门票,没有复现的发现只能当线索。作为维护者:把 AI 审查前移到自己的 CI,在别人找到之前先找到;同时在 SECURITY.md 里写明报告必须附可运行的复现。
# .github/workflows/security.yml:Anthropic 官方 action,只扫 PR diff
name: Security Review
permissions:
pull-requests: write
contents: read
on:
pull_request:
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
fetch-depth: 2
- uses: anthropics/claude-code-security-review@main
with:
comment-pr: true
claude-api-key: ${{ secrets.CLAUDE_API_KEY }}