返回文章列表

AI 把 Bug 修好了,却悄悄引入了漏洞:什么是代码编辑中的安全漂移?

功能测试通过,不代表一次 AI 代码修改没有改变安全风险。结合 WeSCE 的 400 个可执行样本,讲清安全漂移是什么、为什么会被普通回归漏掉,以及团队如何建立可落地的 Security Diff Gate。

AI 修复了登录超时,回归测试全部通过,代码也顺利合并。几天后,安全扫描却发现:为了让重试逻辑更灵活,新代码把未经校验的外部输入带进了危险调用。Bug 的确没了,但系统并没有因此变得更安全。

AI 代码编辑中的安全漂移
图 1:功能问题从红色变为绿色,不代表安全风险也同步归零;代码修改前后的风险差值需要被单独验证

过去我们评价 AI 编程,最常问两个问题:代码能不能运行,测试能不能通过。现在还要补上第三个问题:这次修改之后,系统的安全风险发生了什么变化?

2026 年 8 月发布的 WeSCE 研究,把这种变化称为 Security Drift,安全漂移。它关注的不是“让 AI 专门修一个已知漏洞”,而是更常见的开发现场:需求只要求新增功能、删除功能、修 Bug 或重构,没有明确提醒安全事项,安全属性却随着代码变化悄悄移动。

先把结论说在前面:安全漂移不等于风险必然上升。它可能变好、变坏,也可能只是从一种漏洞转成另一种漏洞。真正危险的是,团队只验证功能差异,却从未测量安全差异。


一、安全漂移,不是“AI 写了不安全代码”的新说法

“AI 生成代码可能有漏洞”并不新鲜。安全漂移更进一步,它研究的是同一段程序在一次编辑前后,安全风险如何变化

假设旧代码同时存在三个问题:输入校验不足、危险反序列化、异常信息泄露。AI 接到的任务只是“重构这段代码,让结构更清晰”。修改后可能出现四种结果:

结果功能状态安全状态
理想改进功能通过原有风险下降,没有新增风险
风险放大功能通过新增漏洞或严重程度上升
风险迁移功能通过旧漏洞消失,但换成另一类漏洞
表面重构功能通过代码更漂亮,危险逻辑原封不动

普通的“有漏洞 / 没漏洞”二元判断很难描述后两种情况。修改前后都被扫描器标记为“有漏洞”,但风险的类型、数量、位置和严重程度可能已经完全不同。

因此,安全漂移至少要看三个维度:

  • 总体风险有没有上升:低、中、高风险信号综合起来,修改后是增是减;
  • 最严重的问题有没有变坏:即使漏洞总数减少,只要新增一个高危问题,就不能说更安全;
  • 漏洞结构有没有迁移:SQL 注入消失了,却出现命令注入,数量不变不代表风险没变。

这和性能回归很像。接口仍然返回 200,不代表响应时间没有从 200 毫秒漂移到 2 秒;同样,测试仍然全绿,也不代表安全属性没有漂移。


二、WeSCE 是怎么测量这件事的

WeSCE 的全称是 Weak-Security Code Editing。这里的“弱安全约束”不是说系统安全不重要,而是说给模型的任务只描述功能目标,不主动提示“请检查安全”。这更接近很多团队日常使用 AI 编程助手的方式。

研究团队以 GitHub 和 Real-Vuln-Benchmark 中的真实漏洞种子为基础,扩展、筛选并去重出 400 个可执行程序。四类任务各 100 个:

  • ADD:新增功能;
  • REMOVE:删除功能;
  • FIX:修复普通 Bug;
  • REFACTOR:重构代码。

每次编辑前后,研究都使用同一套方法检查代码:CodeQL 和 Bandit 做静态分析,Atheris 用固定 90 秒预算做动态模糊测试,再把漏洞数量、严重程度、代码规模和漏洞分布组合成连续风险指标。它不是只问“扫描器有没有报警”,而是比较修改前后的差值。

Security Diff Gate:先验证功能,再比较修改前后的安全差值
图 2:同一套安全规则分别扫描修改前后的代码,功能回归与安全差异共同决定是否允许合并

论文还对 40 个随机样本做了人工核验。作者报告,这套检测管线在该子集上达到 94.6% 的精确率和估算的 97.2% 召回率。这个数字说明研究者尝试控制静态扫描误报,但它仍是论文数据,不等于任意企业代码库都能复现相同效果。

最值得注意的三个结果

第一,强模型通常会顺手降低一部分风险,但远没有“自动安全”。

在论文测试的八个模型中,表现靠前的模型在约 79%~82% 的样本上降低了最坏情形风险;但“风险完整清除率”只有约 50%~51%。换句话说,即使总体趋势向好,大约一半样本仍保留非轻微风险。

第二,修 Bug 和重构的结果,整体优于新增和删除功能。

以论文表现最好的一个模型为例,重构任务的最坏风险降低率为 98%,完整清除率为 80%;新增功能则分别只有 71% 和 34%。作者认为,更深入的控制流修改更容易顺带改变已有危险路径,而局部新增往往只是把新逻辑叠上去。

这不能被解释成“重构天然安全”。恰恰相反,重构带来的漏洞分布变化也最大,需要更认真比较前后差异。

第三,代码变得现代、整洁,不代表危险机制被消除。

论文给出的案例中,旧代码使用 eval 执行受外部影响的表达式,属于典型的代码注入风险。模型把代码重构成类和独立方法,结构更清晰,但底层的 eval 仍然存在。功能通过了,代码更像“好代码”了,漏洞却没有动。

可读性改善是代码质量证据,不是安全修复证据。危险的数据流没有被切断,换一个更漂亮的外壳也没有意义。


三、为什么普通回归测试很容易漏掉安全漂移

1. 验收标准只描述“要实现什么”

“修复文件上传失败”“给导出接口增加筛选”“把旧模块重构成服务类”,这些需求都在描述功能目标。如果没有同时写明文件类型校验、导出权限、敏感字段、路径边界等安全不变量,AI 会优先完成最显眼的任务。

这不是 AI 独有的问题。人类开发者也会在交付压力下聚焦验收标准。区别在于,AI 能更快地产生更大范围的代码变更,让遗漏被更快地复制。

2. 测试只证明“目标行为出现了”

一个 Bug 修复用例通常只验证旧问题不再复现。它不会自动检查:

  • 是否为了绕过异常而关闭了证书校验;
  • 是否把参数化查询改成了字符串拼接;
  • 是否扩大了文件、目录或网络访问范围;
  • 是否在日志和错误响应里暴露了密钥或用户数据;
  • 是否放宽了授权条件,让其他角色也能通过。

测试通过证明了需求路径正确,不证明所有安全属性保持不变。

3. 代码审查容易被“修复成功”锚定

审查者知道这次 PR 是修登录超时,就会自然地盯住重试、超时和异常处理。只要测试变绿、代码看起来合理,注意力很难主动转向权限、输入来源和敏感数据流。

AI 生成的解释也可能强化这种锚定:它会详细说明自己如何解决原 Bug,却不会主动列出所有没有检查过的安全边界。

4. 只看扫描后的绝对结果,没有修改前基线

扫描器报告 12 个问题,这到底是好是坏?如果修改前有 18 个,可能总体改善;如果修改前只有 4 个,就是明显退化。没有基线,团队只能看到一个静态快照,看不到漂移方向。


四、把 Security Diff Gate 接进开发流程

WeSCE 提供的是研究框架,不是可以原样搬进所有项目的发布流程。下面这套做法是基于论文方法与安全测试实践给出的工程化方案。

第一步:在修改前写下安全不变量

不要只把“修复 Bug”交给 AI,还要告诉它哪些边界不能被改变。不同模块可以维护一份短小的安全契约:

模块至少保持的安全不变量
登录与会话失败限速不放宽;旧 Token 按规则失效;错误信息不泄露账号状态
数据查询所有用户输入继续参数化;对象级授权不能被绕过
文件处理路径不能逃逸允许目录;类型和大小由服务端验证
外部请求目标地址受白名单或私网规则约束;超时和重定向有限制
日志与错误密钥、Token、身份证号等敏感字段不得新增到输出

安全不变量不是要求模型“注意安全”这么一句空话,而是可以被测试、扫描或人工审查的约束。

第二步:保存修改前的安全基线

在 AI 开始编辑前,固定以下信息:

  • 提交哈希和依赖锁文件;
  • 静态扫描工具、版本、规则集与忽略配置;
  • 已知问题及其接受理由;
  • 关键安全测试和模糊测试语料;
  • 当前最高风险等级和漏洞分布。

基线的目的不是替旧漏洞开脱,而是让你能准确回答“这次修改新增了什么、消除了什么、把什么挪到了别处”。

第三步:功能回归和安全差异同时运行

一次 AI 修改至少要经过两条独立判定线:

  • 功能线:原 Bug 是否修复,已有行为是否回归通过;
  • 安全线:同一套规则扫描修改前后,新风险、残留风险和最坏风险分别如何变化。

根据技术栈选择工具。论文使用 CodeQL、Bandit 和 Atheris;真实项目还可能需要依赖成分分析、密钥扫描、授权测试或面向业务状态的动态测试。工具名称不是重点,前后使用同一配置并保留可比较结果才是重点。

第四步:按“差异”而不是“总数”做分级

安全差异可以分成五类:

类型处理原则
新增高危或严重问题阻断合并,必须定位或证明误报
已知问题严重程度上升阻断合并,重新评估影响
漏洞类型迁移不能用“一增一减抵消”,分别评审
原问题仍在不宣称完成安全修复;记录残余风险
风险下降且无新增可以进入人工复核,但仍需通过功能与业务检查

关键原则是:十个低危消失,不能抵消一个新增高危。 漏洞数量不是可以简单加减的积分。

第五步:高风险修改必须由人审查数据流

以下变化不宜只依赖扫描器:认证与授权、金额和订单状态、动态执行、反序列化、文件路径、外部网络请求、加密与密钥、日志和隐私数据。

人工审查至少沿着一条完整链路追踪:外部输入从哪里进入,经过哪些校验,最终流向数据库、文件、命令、模板、网络请求还是日志。很多业务越权和环境相关问题,本来就不容易被通用扫描器识别。

第六步:把证据留在 PR,而不是只留一句“已检查”

建议每个 AI 辅助 PR 都保存:

  • 使用了什么模型、工具与指令边界;
  • 功能测试运行结果;
  • 修改前后扫描摘要;
  • 新增、消除、残留和迁移的风险;
  • 人工复核过的高风险数据流;
  • 未执行的检查、原因和剩余风险。

这样即使模型、扫描规则或业务背景以后变化,团队仍能复盘当时凭什么允许合并。


五、一个低成本、可复现的团队实验

如果你不确定安全漂移在自己的项目里是否真实存在,不需要马上建设复杂平台。可以先做一个 48 次编辑的小实验。

数据与分组

  • 从历史记录中选择 12 个已经修复、能够离线执行的普通缺陷;
  • 覆盖新增、删除、修复、重构四类任务,每类 3 个;
  • A 组只给功能要求;
  • B 组在同样功能要求后补充模块安全不变量;
  • 每个条件重复 2 次,总计 12 × 2 × 2 = 48 次编辑。

不要使用生产密钥、真实用户数据或无法隔离的关键系统。两组必须使用相同模型版本、上下文、工具权限和采样配置,否则结果无法比较。

记录五类指标

指标回答的问题
功能通过率AI 是否真的完成任务
新增风险率有多少修改引入了修改前不存在的问题
最坏风险变化最高严重程度是否上升
完整清除率修改后是否仍保留非轻微风险
成本与误报每次检查耗时、Token、扫描误报和人工复核时间

提前写好停止条件

  • 任一方案出现新的严重风险,立即停止该样本并人工复核;
  • 扫描告警人工确认误报超过 30%,先调整规则,不继续堆样本;
  • 两轮实验中 B 组都没有改善新增风险率或最坏风险,停止扩大实验,检查安全不变量是否可执行;
  • 超出预设 Token 或人工复核预算时停止,不用更多调用掩盖设计问题。

最终不要只比较“哪个模型更强”,而要回答更有用的问题:加上明确安全契约后,新增风险是否下降?哪类改动最容易漂移?什么检查最费时间?哪些风险必须人工判断?


六、测试工程师可以直接使用的检查清单

修改前

  • [ ] 原 Bug、验收标准和禁止改变的行为已经明确
  • [ ] 认证、授权、输入、数据、文件、网络和日志边界已识别
  • [ ] 已保存安全扫描基线、规则版本和已知问题
  • [ ] AI 只获得完成任务所需的最小工具与数据权限

修改后

  • [ ] 原 Bug 的复现用例已由失败变为通过
  • [ ] 相关回归测试没有被删除、放宽或绕过
  • [ ] 使用相同规则比较了修改前后的静态与动态结果
  • [ ] 新增高危、严重程度上升和漏洞迁移分别处理
  • [ ] 高风险数据流已由人复核,扫描器未覆盖项已记录

合并前

  • [ ] PR 中保留功能结果和 Security Diff 摘要
  • [ ] 没有用“总告警减少”掩盖新增严重风险
  • [ ] 未解决问题有责任人、风险说明和关闭条件
  • [ ] 结论写的是“已验证什么”,而不是笼统的“AI 已检查”

七、别把一篇预印本写成普遍定律

WeSCE 给出了一个很有价值的观察框架,但它仍是一篇 2026 年 8 月发布的预印本,结果尚不能直接代表所有企业项目。

论文自己列出了几项重要限制:实验程序大约只有 200 行,远小于真实的多模块代码库;动态部分主要通过 Atheris 捕捉输入驱动崩溃和部分运行时问题,可能漏掉业务逻辑、权限和环境相关漏洞;模型没有收到显式安全指令,因此无法完全区分改进来自任务本身还是预训练中已有的安全知识。

此外,研究中的程序不是把真实大型仓库原样拿来测试,而是以真实漏洞种子为基础扩展出的可执行样本。它适合做受控比较,不等于生产环境复现。

所以本文能够确认的是:功能驱动的代码编辑会改变安全属性,而只看功能测试不足以描述这种变化。 至于某个模型在你的仓库里会让风险上升还是下降,必须使用你自己的数据、规则和人工复核去验证。


写在最后

AI 编程让“改代码”越来越便宜,但它没有让“证明改得安全”自动变便宜。

一个 Bug 被修复,只能说明目标问题消失了;测试全部通过,只能说明已有断言没有发现回归;扫描告警变少,也不代表风险结构没有迁移。真正可靠的交付,需要把代码修改看成一次状态变化,同时比较功能、安全和证据。

不要只问 AI 修好了什么,还要问:它改动之后,什么风险消失了,什么风险留下了,又有什么风险是新出现的?

当安全不变量、修改前基线、Security Diff Gate 和人工数据流审查形成闭环,AI 才不只是一个写得快的开发者,而是一个能够被质量体系约束、被证据复核的代码编辑者。


参考资料

说明:文中的论文数据均来自 WeSCE 作者报告,尚未由本文独立复现实验;Security Diff Gate、团队实验和发布检查表是基于论文方法给出的质量工程建议。

版权与声明

本站所有内容仅代表作者个人观点,与作者供职的公司、客户或其他关联机构无关。

本文除特别声明外,采用 CC BY-NC-SA 4.0 许可协议。转载或改编请署名、附原文与许可证链接,并标明改动;不得用于商业用途,演绎作品须以相同许可发布。

评论