为什么 Codex Security 不包括 SAST 报告

发布: (2026年3月16日 GMT+8 08:00)
11 分钟阅读
原文: OpenAI Blog

Source: OpenAI Blog

静态应用安全测试(SAST) vs. Codex Security

数十年来,静态应用安全测试(SAST)一直是安全团队扩展代码审查规模的最有效方式之一。

在我们构建 Codex Security 时,做了一个刻意的设计选择:我们并没有先导入静态分析报告并让代理对其进行分流。相反,我们设计系统从 代码仓库本身——其架构、信任边界和预期行为——开始,并在让人类介入之前先验证它所发现的内容。

为什么要转变?

最棘手的漏洞往往不是简单的数据流问题。它们发生在代码看似执行了安全检查,但该检查并未真正保证系统所依赖的属性。换句话说,挑战不只是追踪数据在程序中的流动——而是判断代码中的防御是否真的有效。

经典的 SAST 模型

SAST 通常被描述为一个简洁的流水线:

  1. 确认不可信输入的来源。
  2. 跟踪数据在程序中的流动。
  3. 标记那些在未消毒的情况下到达敏感 sink 的情况。

这是一个优雅的模型,能够覆盖大量真实的 bug。

然而在实际使用中,SAST 必须做出近似,以在规模上保持可处理——尤其是在存在间接引用、动态分派、回调、反射以及框架重度控制流的代码库中。这些近似并不是对 SAST 的批评;它们是尝试在不执行代码的情况下推理代码的现实。

注意:不是 Codex Security 不从 SAST 报告开始的唯一原因。

更深层的问题:源‑到‑sink 追踪之后

即使静态分析能够正确追踪跨多个函数和层级的输入,它仍然必须回答一个真正决定漏洞是否存在的问题。

示例模式:

# Pseudocode
sanitize_html(user_input)   # sanitizer runs
render(user_input)          # untrusted content rendered

静态分析器可以看到消毒函数被调用,但通常无法判断该消毒函数对于特定的渲染上下文、模板引擎、编码行为以及后续转换是否足够。

关键区别:

  • “代码调用了消毒函数。”
  • “系统是安全的。”

后者需要推理检查的 有效性,而不仅仅是其是否存在。

真实案例说明

一个 Web 应用接收 JSON 负载,提取 redirect_url,使用白名单正则进行校验,随后进行 URL 解码,并将结果传递给重定向处理器。

经典的源‑到‑sink 报告会是:

untrusted input → regex check → URL decode → redirect

真正的问题是 在随后的转换之后,校验是否仍然约束了该值

  • 如果正则在解码 之前 运行,它真的能约束 解码后的 URL 吗?而重定向处理器是如何解释该 URL 的?
  • 要回答这个问题,需要推理整个转换链:正则、解码/规范化、URL 解析的边缘情况以及重定向逻辑。

许多实际漏洞都呈现出这种形式:操作顺序错误、部分规范化、解析歧义以及验证与解释之间的不匹配。数据流是可见的;弱点在于约束如何(或未能)在转换链中传播。

具体案例:
CVE‑2024‑29041 – Express 曾受到一个开放重定向问题的影响,恶意构造的 URL 能绕过常见的白名单实现,因为重定向目标在编码后再解释的方式导致验证失效。数据流本身很直接;更难的、决定漏洞是否存在的问题是验证在整个转换链之后是否仍然成立。

Codex Security 如何解决该问题

Codex Security 的核心目标很简单:通过提供更有力的证据来降低 triage 工作量。在产品中,这意味着使用特定仓库的上下文(包括威胁模型),并在隔离环境中验证高信号的漏洞后再将其呈现出来。

当 Codex Security 遇到看似“验证”或“消毒”的边界时,它不会把它当作一个检查框来处理。它会尝试理解代码试图保证什么——然后尝试推翻该保证。

典型工作流程

  1. 上下文代码阅读

    • 像安全研究员一样,结合完整的仓库上下文阅读相关代码路径。
    • 寻找意图与实现之间的不匹配(包括注释,尽管模型不会盲目相信它们)。
  2. 隔离最小可测试切片

    • 在转换管道周围提取一个极小的代码切片。
    • 为该切片编写微模糊测试(micro‑fuzzers)。
  3. 推理跨转换的约束

    • 将检查视为链条的一部分,而不是独立的闸门。
    • 在适当情况下,将问题形式化为可满足性问题(例如,使用带有 z3‑solver 的 Python 环境)。
    • 这对整数溢出或特定架构的 bug 特别有用。
  4. 在沙箱中执行假设

    • 在沙箱化的验证环境中运行隔离切片。
    • 区分“这可能是个问题”和“这确实是个问题”。
    • 使用调试模式编译的完整端到端 PoC 能提供最有力的证明。

结论

  • SAST 告诉你 数据流向何处
  • Codex Security 则询问 应该阻止该数据的约束在所有转换后是否仍然成立

通过结合仓库范围的上下文、针对性的隔离、形式化推理以及沙箱执行,Codex Security 能够呈现更高置信度的发现,显著降低手动 triage 的负担。

关键转变

与其停留在 “a check exists,”,系统应当推进到 “the invariant holds (or it doesn’t), and here’s the evidence.” 模型随后会为此任务选择最合适的工具。

合理的反应

为什么不两者兼顾?
先从 SAST 报告开始,然后使用代理进行更深入的推理。

为什么从 SAST 报告开始会产生可预测的失败模式

1. 过早收窄

  • 发现列表是工具 已经检查过 的位置的映射。
  • 将其作为起点会使系统倾向于:
    • 在相同区域投入不成比例的精力。
    • 重复使用相同的抽象。
    • 漏掉不符合工具世界观的类问题。

2. 隐式、难以解开的判断

  • 许多 SAST 发现包含关于 消毒、验证信任边界 的假设。
  • 如果这些假设错误或不完整——把它们喂入推理循环会把代理从 “调查” 转向 “确认或驳回”,这并非预期行为。

3. 评估困难

  • 当流水线以 SAST 输出开始时,难以区分:
    • 代理通过 自身分析 发现的内容。
    • 从其他工具 继承 的内容。
  • 这种区分对 准确衡量 系统能力以及 持续改进 至关重要。

我们的方法:Codex 安全

我们构建 Codex Security,以从安全研究的起点开始:

  • 从代码和系统的意图
  • 验证仅用于在我们打断人类之前提升置信度

当 SAST 工具发挥优势时

  • 强制执行安全编码标准
  • 捕获直接的源到汇问题。
  • 可预测的权衡在大规模上检测已知模式。
  • 它们可以成为纵深防御的有力组成部分。

本帖范围

  • 专注于为什么一个旨在推理行为并验证发现的代理不应以静态发现列表为锚点开始工作

超越源到汇的思考

  • 并非所有漏洞都是数据流问题。
  • 许多真实的故障是 状态和不变性问题
    • 工作流绕过。
    • 授权缺口。
    • “系统处于错误状态” 的 bug。

对于这些 bug,受污染的值 不会 到达单一的“危险汇”。
风险在于 程序假设永远为真的内容

前瞻

我们预计安全工具生态系统将持续改进:

  • 静态分析
  • 模糊测试
  • 运行时防护
  • 代理式工作流

所有这些都会发挥作用。

我们希望 Codex Security 擅长的领域

“这看起来可疑” 转化为 “这是真的,以下是它的失败方式,以及一个符合系统意图的修复方案。”

这是安全团队成本最高的部分,也是 Codex Security 旨在提供最大价值的地方。

0 浏览
Back to Blog

相关文章

阅读更多 »