传统 SAST 很难处理的问题,比如越权访问、业务逻辑、接口语义、上下文判断,借用 AI 有机会提供新的帮助。
传统 SAST 擅长模式识别、数据流分析、语法结构匹配,比如某个输入是否进入危险函数,某个参数是否经过过滤,某类 API 是否被错误使用。这些问题规则可以写,路径可以追,结果也比较稳定,但问题在于规则解决不了代码理解的问题:
这段代码是否符合业务意图?
这个接口是否绕过了权限模型?
这个判断条件在产品逻辑里是否成立?
某个用户在某种状态下是否不该看到这些数据?
这些问题不是单纯的语法问题,而是语义问题、场景问题、设计问题,而 AI 的优势在于它能读懂注释、接口命名、业务描述和代码行为之间的偏差。所以,AI 用在代码安全审核上并不是噱头,只是问题在于,很多产品企图将 AI 替代传统 SAST,更准确的说法是:AI 可以成为静态分析之后的一层理解、分诊和推理能力,它可以补足传统规则难以表达的部分,但那些已经稳定、便宜、确定的能力依然是传统规则化的优势。能用规则解决的问题,就不要浪费模型,能用 Semgrep、CodeQL 提取的信息,就不要让 AI 在几十万行代码里凭感觉搜索(耗时耗钱且结果不稳定),就像让一个资深医生看病:我们当然希望他有经验、有判断,但你不会要求他不用体温计、不看化验单、不拍片子,只回复我们一句——“我感觉你这里可能有点问题”,只是他的感觉更严重一些罢了。
AI 最大的问题是有效上下文不可靠
很多人对 AI 代码审查的第一反应是:模型上下文窗口越来越大,直接把整个项目文件喂给 AI 岂不完美?实际上,模型厂商宣传的是“最多能接受多少 token”,但真实工程实践中更重要的是“在多少 token 以内,模型还能稳定推理”,这就像新能源电车的理论里程和实际里程不同一样。一个模型可以接收几十万甚至上百万 token,但这并不意味着它能同等质量地理解这些内容。上下文越长,模型就越容易出现注意力漂移、早期信息遗忘、幻觉增加、回答不稳定等问题。可能很多人都曾经遇到过类似情况:刚开始模型还记得你的要求,聊到后面就开始偏题;前面提供过的约束,后面又被它忽略;同一段代码,换一次运行就给出不同判断。但直觉告诉他们,这是自己提示词的问题,而不是模型 token 上下文的问题,这就是所谓的上下文腐烂。在安全代码分析的场景里,这个问题更会被放大。因为安全分析不是做摘要任务,也不是简单问答,而是要求模型在大量代码里找到相关部分,理解调用关系、数据流、权限边界、业务语义,然后判断安全风险是否真实存在。这不是“能不能看到某段代码”的问题,而是“看到了以后还能不能正确推理”的问题。所以,把整个仓库塞给模型,很多时候只是把问题从“上下文不够”变成“上下文太乱”罢了。模型看似拥有了全部的代码文件用于分析,但实际却不知道重点在哪里,它可能抓住一个无关细节反复分析,也可能漏掉真正关键的调用链。这就是为什么,在工程实践中,尤其是 AI 的工程实践中,可靠性、稳定性、一致性是重中之重的关键,单次的效果或成果并不能说明工程化的成功。所以与其问 AI “这个项目有什么漏洞?”不如问“这几个路由处理用户输入,其中XX参数经过了XX函数,最后进入了这个输出位置。在这种上下文下,是否存在 XSS 风险?”前者像让人在图书馆里随便找一本有问题的书,后者像把书、页码、段落和问题类型都摆在桌上,请他做判断。
SAST 的核心是代码上下文工程
如果我们仔细分析,会发现一个 SAST+AI 模式的系统通常包含四类要素。第一类是输入,也就是要审查的代码、函数、调用链、HTTP 请求响应、配置文件等。第二类是提示词,也就是你到底让模型判断什么。是找 XSS,还是看授权绕过,还是分析加密 API 是否误用。第三类是RAG(Retrieval-Augmented Generation),也就是与漏洞类别相关的背景知识。例如某类漏洞的常见模式、安全编码规范、漏洞案例、修复建议等。第四类是上下文,也就是这段代码在当前项目里的具体位置。比如调用者是谁,数据从哪里来,权限在哪里检查,框架如何处理输入输出,相关配置是什么。有的人实际上并不会真正使用 AI,最后仅仅是用一句粗暴的提示词:“请找出这段代码中的安全漏洞。”这样的用法不是完全没用,如果一个团队此前什么都不做,只是把 PR 或关键模块交给 AI 看一遍,也可能会得到一些有价值的结果,尤其是让 AI 解释 PR 做了什么、可能影响哪些区域、有没有明显 bug。但真正有效的 AI-Native SAST,应该是,先用传统工具提取结构化信息:哪些是路由,哪些是入口点,哪些函数处理用户输入,哪些地方调用危险 API,哪些调用链跨越了权限边界。然后把这些信息交给 AI ,让 AI 做更适合它的事情:理解意图、判断合理性、比较代码行为和安全预期之间的差异、帮助分诊误报、生成可读报告。也就是说,AI 不应该被用来做所有事情,AI 应该被用在传统工具不擅长,但语言理解和场景需要推理的地方。这就是所谓上下文工程,不是把我们想要的统统塞给 AI ,而是把更相关、更干净、更有结构的东西交给模型(事实上绝大多数人使用豆包等 AI 应用都是期望用笼统的输入和笼统的提问期望得到一个精确的回答,但往往并不如意)。
四种常见的 SAST + AI 路线
第一种是提示词加代码。也就是把一段代码丢给模型,问它有没有安全漏洞。这种方式成本最低,启动最快,也最容易产生幻觉和噪音,它非常适合做初步尝试,也适合在 PR 审查中补充说明,但不适合承担核心安全流程。第二种是提示词加 Agent。让 AI Agent 在代码仓库里搜索、读取文件、记录分析结果。这比单次问答强,因为 Agent 可以迭代探索。但它仍然依赖模型自己的搜索策略。模型很容易被一些边边角角的代码吸引,也容易在长任务中丢失原始目标。第三种是定制提示词加 SAST 。先运行静态分析,再把命中的热点交给 AI 判断。例如,规则先提取出所有使用 `innerHTML` 的位置,再让 AI 判断这些位置是否真的存在 XSS 风险。或者提取所有使用加密库的代码片段,再让 AI 判断是否存在不安全算法、错误模式或密钥处理问题。这种方式可以省 token、降噪声、提升命中率,模型也不再漫无目的地找问题,而是在一个明确的上下文中做判断。第四种是 Agent 加代码图加 SAST 工具。系统提前构建 AST、调用图、数据流、入口点、组件关系,然后通过 MCP 或其他工具接口暴露给 Agent。Agent 不再只是 grep 文件,而是可以查询:“这个函数的调用者有哪些?”“这个参数是否来自用户输入?”“从这个路由到数据库写入之间经过了哪些函数?”这时,AI 的工作流才更接近人类的做法,因为它有了合适的工具和上下文。
AI 适合做分诊,但不能替代规则
当下的许多 SAST 厂商的做法是让 AI 分诊 SAST 结果,也就是在 SAST 输出的漏洞信息旁提供一个漏洞判断的功能,通过 AI 检查该漏洞是不是误报,因为传统 SAST 最大的问题就是误报。这个思路实现起来最简单,且最容易显得像是蹭到了 AI 的风潮。但这里有一个容易被忽略的问题:如果规则本来已经非常精确,AI 判断可能反而是多余的,又或者,如果规则本身就有问题,AI 针对单个漏洞有限的上下文判断并不能降低漏报和漏报。AI 更适合处理宽泛的、有可疑的规则,比如提取所有路由,不代表每个路由都有问题;提取所有加密 API 使用点,不代表每个地方都不安全;提取所有模板渲染位置,不代表一定有注入风险。这些地方都需要语义判断,且 AI 可以参与。也就是传统 SAST 负责稳定提取,AI 负责语义分析,两者配合比单独使用任何一方更有价值。
许多甲方的人员会有一种错觉:只要买了新的安全工具或产品,安全能力就得到了跨越式的升级。如果一个安全团队没有资产梳理,没有规则维护,没有代码审查机制,没有误报处理流程,没有修复责任人,那么 AI 只会制造更多看起来很高级、很漂亮,但又束之高阁的报告。相反,如果一个团队已经有基础 SAST、CI 流程、PR 审查、规则治理和修复闭环,那么 AI 可以明显提升效率。它可以帮助解释复杂结果,发现传统规则难以表达的语义问题,降低分诊成本,并让安全分析更接近真实业务场景。所以,AI-Native SAST 的关键是它有没有解决以下问题:
它怎么选择代码片段?
它怎么构造上下文?
它怎么利用已有静态分析结果?
它怎么减少误报?
它怎么证明自己的判断?
它怎么进入现有研发流程?
如果这些问题搞不清楚,那么所谓 AI-Native 也只是把“找漏洞”这件事包装成了一次昂贵的聊天记录而已。结合 AI 后的 SAST 是一次重新组织静态分析流程的机会。真正值得做的不是把代码扔给模型然后等奇迹发生,而是用静态分析、上下文工程和安全经验把 AI 变成一个更可靠的审查环节。参考资料