谷歌AI挖出500个漏洞 我干了8年渗透测试反而更值钱了
原创
紫禁
紫禁
紫禁玄科
2026年10月7日 23:14
四川
在小说阅读器读本章
去阅读
在公众号小说中沉浸阅读
SECURITY · INTELLIGENCE
谷歌AI挖出500个漏洞 我干了8年渗透测试反而更值钱了
2026年10月07日 · 10 min
网络安全#安全行业#个人观点
01
500 这个数字,昨天把我的群聊炸了
AI 挖洞,人更值钱——这是我看完这条新闻的判断
早上刷到 Dark Reading 那条新闻的时候,我正在给一个客户写报告的收尾段落:Google 内部一个叫 PageBreak 的 AI agent,在自家 Web 应用里挖出了 500 多个跨站脚本漏洞。
我把链接随手丢进一个渗透测试的小群。三分钟后,收到一句私信:「哥们,你是不是要失业了。」
我没回,因为一句话说不清楚。今天这篇不写教程,也不复现漏洞,就写写我的判断——毕竟这事儿直接关系到我往后几年怎么吃饭。
先把结论撂在前面:不会失业。但你得换一种方式值钱。
02
先把这个新闻拆干净,别只看标题
业内有个毛病,看到「AI 挖出 500 个漏洞」就自动脑补成「AI 已经比人强了」。我把原文翻了一遍,事实是这样的。
PageBreak 是 Google 自己产品安全团队做的,用来测自家第一方 Web 应用。2025 年 11 月试点,2026 年 1 月转成正式产品。Google 的信息安全工程师 Michał Bentkowski 在博客里写的目标是:自主扩大漏洞发现的规模,同时把人从重复劳动里解放出来。
它找到的东西里,挑三个公开的说:apis.google.com 上的一个缓存投毒、admin.google.com 上的一个 XSS、还有浏览器扩展里不安全的外部握手。三个都已经修了。底层跑的是 Gemini 3.1 Pro 和 3.5 Flash,官方说换别的模型也行。
到这里为止,其实没多新鲜。AI 会挖洞这件事两年前就不是新闻了。
真正值得记的是另一件事:「挖洞」第一次被工业化了。过去一年我们讨论的都是「AI 能不能找到漏洞」,现在的问题变成「找到 500 个之后怎么办」。这两件事的答案,完全不是一回事。
03
说实话,最聪明的不是那个 AI
我把这个项目安利给同行的时候,十个人里有九个没注意到博客里最关键的一句:PageBreak 配了一套非 AI 写的确定性验证器。
流程是这样的:AI 提出「这里可能有个洞」的假设 → 把假设交给验证器 → 验证器在一个真实运行的环境里跑一个真实 payload → 只有能被复现的,才写进报告。
Bentkowski 自己点破了痛点。他说以前最难的,是「分清一个真实可利用的漏洞,和一个一本正经的胡说八道」,而这活儿以前是直接甩给产品团队的——等于 AI 挖得越欢,工程师被折腾得越惨。
Detectify 的 CEO Rickard Carlsson 有句话说得极准,我抄在这儿:「你不该让一个 agent 给自己的作业打分。」
AI 提假设,人来验证——别让 AI 自己给自己打分
我的判断是:这个行业最贵的一个误会,就是把「找到」当成「风险」。
找到 ≠ 能打穿。能打穿 ≠ 影响面大。影响面大 ≠ 现在就得修。这中间每一层转换都需要证据,而证据这件事,恰恰是 AI 最不擅长、也最不该由它自己认定的。Google 那套方案之所以让人眼前一亮,不是因为它聪明,是因为它肯承认自己会说谎。
04
说个真事,我今年被 AI 报告坑过不止一次
今年开始,越来越多甲方不再直接找我做测试,而是先丢一份「AI 扫描报告」过来,让我复核。
实话说,里面大概有一半是幻觉。漏洞写得有鼻子有眼,危害描述得人心惶惶,我照着 payload 一跑——什么都没有。有的连参数名都是编的。
你猜怎么着,最耗时间的从来不是找洞,是证明某个洞根本不存在。我要写清楚「这条为什么不算」,比写清楚「这条怎么利用」麻烦得多。
那这是不是说明 AI 挖洞没用?也不对。剩下那一半里,有几条是我靠肉眼翻代码绝对翻不出来的——跨模块、跨服务的调用链,A 服务的输出被 B 服务当信任输入,人眼在这种规模面前会漏,AI 不会。
所以我既不站「AI 挖洞是噱头」那一边,也不站「AI 挖洞要取代人」那一边。我站的是中间那条线:AI 挖洞必须配验证器,否则它产出的是噪音,不是情报。
05
哪三类活儿会被商品化,哪三类不会
说点同行关心的。我的判断是,这行的工作会迅速裂成两半。
会被迅速商品化的三类:
1. 模板化挖洞。反射型 XSS、SQL 注入、已知 CVE 版本比对——这类活儿有固定的套路,机器一天扫 500 个不是梦。Google 这 500 多个,绝大多数就是这一类。 2. 资产清点。端口、组件、版本号、暴露面,本来就是机器该干的活儿,人干这个纯属浪费。 3. 报告初稿。格式化、复述证据、套风险评级模板。你见过凌晨三点还在调 Word 样式的安全工程师吗,那部分时间本来就该省掉。
雷打不动还是人的三类:
1. 业务逻辑漏洞。先查后扣、并发抢券、越权改价、退款到账顺序——AI 不知道「这门生意本来该怎么算钱」,它只能看见代码,看不见规则。今年我做的业务逻辑项目里,没有一个是扫出来的。 2. 攻击链编排。拿一个低危当跳板,横穿网段,最后打到域控。这是判断和编排,不是模式匹配。 3. 验证与定责。「这条到底算不算漏洞、影响多大、现在修还是下个版本修」——这是要签字的活儿。Google 那套验证器之所以是非 AI 写的,就是这个原因。
会找漏洞,不等于会打穿,更不等于敢下结论
浓缩成一句话:会找 ≠ 会打穿 ≠ 会定罪。过去你的报价单上写「扫出 300 个漏洞」,往后这句话一文不值——因为机器一天能给你 500 个。往后值钱的是「我能证明这 12 条真能打穿,剩下 288 条是噪音」。
06
跟不搞安全的人,到底有什么关系
我知道看到这儿,有些读者会想:我又不做安全,这事儿跟我有什么关系。关系还挺大,而且是两个方向。
好的一面:你每天在用的那些 App,可能会被更早地查出问题。Google 已经在计划把 PageBreak 和 CodeMender(它的自动修复系统)打通——找到一个已验证的漏洞,就自动生成补丁建议交给产品工程师。漏洞从「被发现」到「被修掉」的周期会被压得很短。
坏的一面:同一套能力,黑产手里也有一份,而且他们不需要验证器那么讲究。
所以我反问一句:如果 AI 能在一天之内把一个网站的洞全扒出来,你猜是厂商先扒到,还是黑产先扒到?
答案取决于一件事:谁更早把这套东西装进日常工作流。这就是为什么我把这条新闻当行业拐点看,而不是当八卦看。
对普通用户,落点只有一个:别盯漏洞数量,盯修复速度。一个产品好不好,不看它报了多少洞,看它多快把洞补上。
07
给同行的三句大实话
如果你也是吃这碗饭的,下面三句是我这几天想得最清楚的。
AI 挖洞的正确打开方式——每往前一步都要留下证据
第一句,把报价单换掉。别再写「我们能扫出多少漏洞」。改成「我们能证明多少条真能打穿,能给出多久的修复承诺」。前者会被机器打到白菜价,后者不会。
第二句,把验证器思维装进你自己的工作流。不管 AI 给你什么结论,一律用一个确定性脚本去证伪。下面这段就是这个思路的最小实现,拷走就能跑:
脚本一:verify\_xss.py —— 只测转义,不注入任何可执行代码
!/usr/bin/env python3
-\- coding: utf-8 -\-
\"\"\"反射型 XSS 输出编码自查(只对自己拥有或授权的站点使用)
只发一个带 < > \" ' & 的 GET 探针,看服务端回显时有没有做输出编码,
不注入任何可执行代码。用法: python3 verify\_xss.py \"https://站点/search?q=\"
\"\"\"
import sys
import html
import secrets
import urllib.parse
import urllib.request
import urllib.error
PROBE = \"<>\\"'&\"
def audit(base, timeout=15):
if \"=\" not in base:
print(\"用法: verify\_xss.py \\"https://站点/path?参数=\\"(要以 = 结尾)\")
return 2
token = \"xsscan\" + secrets.token\_hex(4)
payload = PROBE + token
url = base + urllib.parse.quote(payload, safe=\"\")
print(\"[\*] 探针:\", payload)
req = urllib.request.Request(url, headers={\"User-Agent\": \"self-escape-audit/1.0\"})
try:
with urllib.request.urlopen(req, timeout=timeout) as r:
body, status = r.read(400000).decode(\"utf-8\", \"ignore\"), r.status
except urllib.error.HTTPError as e:
body, status = e.read(400000).decode(\"utf-8\", \"ignore\"), e.code
except Exception as e:
print(\"[x] 请求失败(网络问题,与安全性无关):\", type(e).\\_name\\_, e)
return 2
print(\"[\*] 状态码:\", status, \" 响应长度:\", len(body))
if token not in body:
print(\"[-] 探针未回显:这个参数不反射,暂无反射型 XSS 攻击面\")
return 0
i = body.index(token)
print(\"[+] 回显窗口:\", body[max(0, i - 15): i + len(token) + 15])
if payload in body:
print(\"[!] 探针原文原样回显 —— 未做输出编码,需要修(输出编码,再加一层 CSP)\")
return 1
if html.escape(payload, quote=True) in body:
print(\"[+] 五个特殊字符全部转义,回显是安全的\")
return 0
print(\"[?] 只转义了一部分,看一眼上面的回显窗口再定性\")
return 1
if \\_name\\ == \"\\main\\_\":
if len(sys.argv) != 2:
print(\\_doc\\_)
raise SystemExit(2)
raise SystemExit(audit(sys.argv[1]))
跑出来是这样。第一个端点没做输出编码,探针原文原样回显,这是真问题:
$ python3 verify\_xss.py \"http://127.0.0.1:8787/search?q=\"
[\*] 探针: <>\"'&xsscanfeda38c3
[\*] 状态码: 200 响应长度: 48
[+] 回显窗口: >
结果:<>\"'&xsscanfeda38c3

评论