大模型+代码分析:我用 AI 找到了10个历史安全漏洞
前段时间我一时兴起,把三年前写的老项目丢给了一个大模型审一审,结果它翻出了我亲手埋的十个安全雷。看着模型一本正经地告诉我:“你这段 SQL 拼接有注入风险”,我竟一时语塞——因为那真的是线上出过事故的地方。于是我开始认真思考:这个 AI 是不是该发年终奖了?今天这篇文章,就带大家复盘一下这场“AI 揪出自己写的锅”的全过程。
🧩 Step 1:引子(Hook)
前段时间我一时兴起,把三年前写的老项目丢给了一个大模型审一审,结果它翻出了我亲手埋的十个安全雷。
看着模型一本正经地告诉我:“你这段 SQL 拼接有注入风险”,我竟一时语塞——因为那真的是线上出过事故的地方。
于是我开始认真思考:这个 AI 是不是该发年终奖了?
今天这篇文章,就带大家复盘一下这场“AI 揪出自己写的锅”的全过程。
🧩 Step 2:实验背景(老代码 + 模型 = 修罗场)
事情的起因是这样:我翻出一个老项目,Spring Boot 1.x + MyBatis 的经典搭配,写的时候很潇洒,审的时候很想跑路。
那项目有啥特征呢?大概是:
- 没有统一异常处理,全靠 try-catch 写出花;
- 参数校验是个传说,连
@Valid
都懒得写; - SQL 靠字符串拼接,XSS 纯靠“心中警钟”;
- 权限控制全靠“大家讲武德”。
我当时心想,这不就是给大模型练刀的完美沙袋?
于是我把整包源码扔进去了,每个 Java 文件作为输入,一次一个,配合一个比较严肃的提示词,长这样:
请你扮演一个资深安全审计专家,分析以下 Java 代码中存在的安全漏洞,类型包括但不限于:
SQL 注入、XSS、未授权访问、敏感信息泄露、文件操作风险、命令注入等。
输出格式:
1. 漏洞类型
2. 涉及文件与行号
3. 相关代码片段
4. 风险说明与危害
5. 修复建议
说实话我本来也没抱太大希望,毕竟 AI 哪懂我这种“野路子风格”写的代码。
结果它第一条就指出了我们当年线上炸过的一条 SQL 注入。
我突然觉得,它好像……真行。
🧩 Step 3:模型识别出的典型漏洞(我写的锅,它全给我端上来了)
模型输出了一大堆结果,我一边看一边喊“卧槽它真懂我”。其中有 3 个让我至今难忘,因为当时真的没人注意过,甚至有一条是上线后安全部门也漏掉的。
1. SQL 注入 - UserController.java:87
String sql = "SELECT * FROM user WHERE username = '" + username + "'";
🧨 风险说明:
这句代码曾是我“快速开发”的得意之作。结果用户一个 ' OR 1=1 --
,系统全门户大开。那次事故之后,我才知道啥叫“拼接就是原罪”。
🔧 修复建议:
把拼接扔了,用 MyBatis 的 #{}
参数绑定。现在看到字符串拼接 SQL,我的手都抖。
2. XSS 漏洞 - ArticleController.java:45
return "<div>" + article.getContent() + "</div>";
🧨 风险说明:
这是个文章渲染接口,本来我以为“用户内容都挺干净的”,直到有人贴了一段 <script>alert('你的网站被我承包了')</script>
。
🔧 修复建议:
所有用户内容输出前都做 HTML 转义,别信用户,信 Apache Commons Text。
3. 命令注入 - BackupService.java:102
Runtime.getRuntime().exec("tar -czf " + filename);
🧨 风险说明:
这段真有杀伤力。传个 filename=/tmp/a; rm -rf /
,恭喜你实现系统自毁。模型当场指出:你这是主动给人开门送刀。
🔧 修复建议:
exec 参数要么用 ProcessBuilder
严格区分参数,要么用白名单校验,永远不要信 filename 里没陷阱。
模型还识别出其他问题,比如:
- 配置文件泄露(密码写死)
- 文件上传不校验文件名
- 接口无登录控制
- 日志输出包含用户 Token
但篇幅所限,我们这次先讲前三个“惊掉我下巴”的。
🧩 Step 4:AI 真有那么神?我来掰扯掰扯
我得实话实说,模型的表现比我想象中靠谱很多,但也远没到“AI 安全部门”那种程度。它有长板,也有短腿。
✅ 它确实有点东西:
1. 能识别常见高频危险模式
只要你写的是“拼接 SQL”、“拼接 HTML”、“拼接 shell 命令”,它准能抓住你尾巴。基本等于“AI 背过了 OWASP Top 10”。
2. 能看懂上下文
不像传统 SAST 工具那样“只看眼前”,它能理解变量的来源、用途,甚至能结合函数注释、方法名一起判断这段代码是干嘛的。看得出来它是“带脑子”在审代码。
3. 解释清楚、说人话
以前审计报告是“发现风险,详见附件 pdf 第 87 页”。它直接一句:“这里 SQL 拼接风险,攻击者可能注入 OR 1=1
”。就这人话解释,甩我以前写的 code review 意见书三条街。
❌ 但它也不是无所不能:
1. 跨文件追踪能力比较弱
比如 controller 里调用了一个 service,service 里再去拼接 SQL,它就容易断片儿。你要是不给它整个链路,它有点懵。
2. 复杂逻辑下会误判
像一些“只有登录状态才会泄露信息”的接口,它有时候会误判成“未授权访问”,把 if 判空当空气。
3. 没有数据流分析能力
你让它做 taint analysis(污点追踪)、CFG(控制流图)、SSA(静态单赋值)?哥们它不是静态分析器,是个聊天机器人,别为难它。
总结一下就是:模型像一个 刚培训完三个月但悟性极高的安全实习生,能找到典型漏洞,也能给出清晰建议,但你不能指望它做逆天代码理解。
好的,下面是 Step 5:结合体验,谈 LLM 在团队里的使用建议与定位。
🧩 Step 5:它不是超人,但能当你团队的“前哨兵”
如果你问我:用大模型查代码漏洞靠谱吗?
我会说:“别全靠它,但真别不用它。”
🌟 最适合的使用场景是这些:
1. 第一轮初筛
就像查错别字一样,模型特别擅长发现“那种明显但我们懒得看的锅”。你让它先扫一遍,再由人类做重点复核,节省精力事半功倍。
2. 安全意识教育
它能在代码 review 阶段直接指出:“你这段可能有 SQL 注入”,而不是过两天上线了才接到安全部门电话说“你这段可能要背锅”。
3. 代码质量辅助审查
别只盯着漏洞,它还会说:“这里重复代码太多”、“这段日志不该输出用户密码”,是那种“既安全又爱唠叨”的队友。
4. 配合 SAST 工具联合巡检
传统 SAST 工具比如用库博静态代码分析找位置,模型补解释 + 修复建议,这一组合拳下来,基本能 cover 80% 的“人力最烦的活”。
🚫 不推荐你指望它的地方:
- 不适合深度漏洞挖掘(比如 race condition、逻辑绕过)
- 不适合分析混淆过、跨多 repo 的巨型项目(除非你给它切好每个模块)
- 不适合独立承担“上线前安全兜底”,它毕竟不是审计专家,是个“懂点代码的大语言模型”
一句话总结:让它当你安全流程里的“提示器”而不是“裁判员”,用得巧,是团队的左膀右臂;用得莽,指不定哪天你拿它生成了漏洞还说“AI 说没问题”。
好的,下面是 Step 6:结尾总结段落,保持轻松自嘲、略带升华的风格,让读者读完有共鸣、有收获,甚至有点想回去试试的冲动。
🧩 Step 6:AI 不替你干活,但能替你长脑子
这次试验对我最大的启发不是“AI 多厉害”,而是——
原来我自己写的老代码,比我记得的还危险。
原来有个会碎碎念的 AI,同样也能帮我“守住底线”。
它不会写出惊世骇俗的检测算法,但它确实能用“程序员能看懂”的语言,指出那些我们早该注意的风险。
未来,我很期待这样的组合出现:
- 上线前:CI/CD 阶段自动调用 LLM + SAST 扫一遍,问题立刻打 tag 标红
- 提交代码时:模型直接拦下来对你说:“兄弟你是不是忘了 escape()?”
- 新人入职:靠它复审一遍代码风格 + 安全意识,一口气省下两个 mentor
我相信:不会被 AI 取代的程序员,早晚会被“会用 AI 的程序员”拍在沙滩上。
所以别抗拒,不如找个时间,把你三年前写的项目也扔进去。
你可能会收获“过去的我给现在挖的坑”,也可能发现“AI 真的比当年的我冷静多了”。
如果你也试了,欢迎评论区爆料你被模型抓住的小秘密 😏
补充实验:结合静态分析图谱,喂给大模型更聪明的提示
刚开始我是“一个文件一个文件”地喂代码,模型能找到不少问题,但也容易卡在函数跳转、跨类引用这类上下文理解上。
后来我加了点“插件增强”:
- 先用静态代码分析工具生成 函数调用图(Call Graph),确定调用链顺序;
- 再生成 数据流图(Data Flow Graph),把 taint(敏感数据)流向画清楚;
- 最后将这些图谱抽象成结构化文本(比如“函数A调用函数B -> B拼接SQL -> 入参来自未校验的GET参数”),一起送给大模型分析。
结果直接提升了模型理解的深度:
- 它开始能识别“你看着没问题,其实是下游拼接了危险字符串”的情况;
- 它能给出完整链路分析,从 controller 到 dao,条理清晰;
- 风险解释也更具体,不再泛泛而谈,而是说“这个值来源于外部未校验参数,经过 A->B->C 三层传递后被拼进 SQL”。
一句话:大模型不是不能分析复杂逻辑,而是你得给它准备足够“好咀嚼”的上下文。
这也启发了我 —— 未来所有“模型代码审查”工具都该内置一个静态分析预处理器,先拆解逻辑关系,再交给模型判断。就像我们看代码不是一行一行盯,而是先看结构、再下结论。
更多推荐
所有评论(0)