Skip to main content

关于 CodeQL 代码扫描的自动修复

了解 GitHub 如何使用 AI 为拉取请求中通过 CodeQL 找到的 code scanning 警报建议潜在修复。

Who can use this feature?

Autofix for code scanning is available only to GitHub Enterprise Cloud users who have GitHub Advanced Security. For more information, see "About GitHub Advanced Security."

注意:**** code scanning 的 GitHub 自动修复功能为 beta 版。 功能和文档可能会有变动。 在此阶段,此功能仅限用于 CodeQL 标识的 JavaScript 和 TypeScript 警报。 如果你有一个企业帐户并使用 GitHub Advanced Security,则可以加入 GitHub Advanced Security AI 功能的候选名单

关于 CodeQL code scanning 的自动修复

自动修复是 code scanning 的 AI 支持的扩展,为用户提供具有针对性的建议,以帮助用户在拉取请求中修复 code scanning 警报,从而避免引入新的安全漏洞。 潜在修复由大型语言模型 (LLM) 使用代码库、拉取请求和 CodeQL 分析中的数据自动生成。

Code scanning自动修复会生成与现有源代码相关的潜在修复,并将警报的说明和位置转换为可能修复警报的代码更改。 自动修复系统使用 OpenAI GPT-4 大型语言模型,该模型具有足够的生成功能,可在代码中生成建议的修复,并为这些修复生成说明性文本。

开发人员体验

GitHub Advanced Security 用户可以使用 CodeQL 来分析其拉取请求,查看code scanning检测到的任何安全警报。 但是,开发人员在代码安全性方面的培训通常很少,因此修复这些警报需要花费大量的精力。 他们必须先阅读并理解警报位置和说明,然后使用该理解来编辑源代码以修复漏洞。

Code scanning自动修复通过将有关最佳做法的信息与代码库和警报的详细信息相结合,向开发人员建议潜在的修复方案,从而降低了开发人员的进入门槛。 开发人员不是从搜索有关漏洞的信息开始,而是从展示其代码库潜在解决方案的代码建议开始。 开发人员评估潜在的修复,以确定其是否为其代码库的最佳解决方案,并确保其保持预期行为。

提交建议的修复或修改的修复后,开发人员应始终验证代码库的持续集成测试 (CI) 是否继续传递,并且警报在合并拉取请求之前显示为已解决。

自动修复生成过程

为存储库启用自动修复时,支持的 CodeQL 查询在拉取请求中识别的 code scanning 警报将输入发送到 LLM。 如果 LLM 可以生成潜在修复,拉取请求中会将该修复显示为建议注释。

GitHub 向 LLM 发送拉取请求和 CodeQL 分析的各种数据。

  • SARIF 格式的CodeQL 警报数据。 有关详细信息,请参阅“对代码扫描的 SARIF 支持”。
  • 当前版本拉取请求分支的代码。
    • 每个源位置、接收器位置以及警报消息中引用的或包含在流路径中的任何位置的简短代码片段。
    • 涉及任何这些位置的每个文件约前 10 行。
  • CodeQL 查询确定问题的帮助文本。 有关示例,请参阅“CodeQL 查询帮助”。

将生成并存储在code scanning后端中的任何自动修复建议。 这些建议在拉取请求中显示为建议注释。 除了在代码库上启用code scanning和创建拉取请求之外,无需用户交互。

自动修复建议的质量

GitHub 使用自动测试工具持续监视自动修复建议的质量。 这样,我们就可以了解随着模型发展 LLM 更改生成的自动修复建议。

测试工具包含一组来自各种公共存储库的 700 多个 JavaScript/TypeScript 警报,其中突出显示的代码具有测试覆盖率。 将会测试这些警报的自动修复建议,以了解其质量,即开发人员在将其提交到代码库之前需要对其进行多少编辑。 对于许多测试警报,LLM 生成的自动修复按原样提交即可修复警报,同时继续成功通过所有现有的 CI 测试。

此外,该系统还进行压力测试,以检查任何潜在危害(通常称为红队测试),LLM 上的筛选系统有助于防止向用户显示潜在有害的建议。

GitHub 如何测试自动修复建议

在运行code scanning和存储库对结果代码进行单元测试之前,我们将通过合并所有建议的更改(未编辑)来测试自动修复建议的有效性。

  1. 建议是否已修复 code scanning 警报?
  2. 修复是否引起了任何新的 code scanning 警报?
  3. 修复是否引起了 CodeQL 可以检测到的任何语法错误?
  4. 修复是否更改了任何存储库测试的输出?

此外,我们还会抽查许多成功的建议,验证其是否修复警报而不会引起新问题。 当其中一项或多项检查失败时,我们的手动审查表明,在许多情况下,建议的修复几乎正确,但需要用户能够识别并手动执行的一些细微的修改。

其他 JavaScript/TypeScript 项目的有效性

测试集包含各种不同类型的项目和警报。 我们预测其他 JavaScript/TypeScript 项目的自动修复应遵循类似的模式。

  • 自动修复可能会向大多数 JavaScript/TypeScript 项目的警报添加代码建议。
  • 当开发人员评估自动修复建议时,我们期望可以在不编辑的情况下提交大多数修复,或者通过次要更新来反映代码更广泛的上下文。
  • 一小部分建议的修复将反映出对代码库或漏洞的重大误解。

但是,每个项目和代码库都是唯一的,因此开发人员可能需要在提交之前编辑较大比例的建议修复。 自动修复提供了有价值的信息来帮助解决 code scanning 警报,但最终仍由你负责评估建议的更改并确保代码的安全性和准确度。

注意:**** 系统不建议修复 CodeQL 标识的所有类型的 code scanning 警报。 默认 CodeQL JavaScript/TypeScript 查询的子集支持自动修复,并且 LLM 的操作能力受到限制。 此外,在将建议的每个修复添加到拉取请求之前都会对其进行测试。 如果没有可用建议,或者建议的修复未通过内部测试,则不会显示自动修复建议。

自动修复建议的限制

查看自动修复建议时,在接受更改之前,必须始终考虑 AI 的局限性并根据需要编辑更改。 在为code scanning启用自动修复之前,还应考虑更新存储库的 CI 测试和依赖项管理。 有关详细信息,请参阅“减少自动修复建议的限制”。

自动修复代码建议的限制

  • 编程语言:__ 支持一部分编程语言,最初仅支持 JavaScript 和 TypeScript。 将添加对其他语言的支持,但无意为所有 CodeQL 语言提供支持。
  • 人类语言:__ 系统主要使用英语数据,包括发送到系统的提示、数据集中 LLM 看到的代码以及用于内部评估的测试用例。 LLM 生成的建议对于使用其他语言编写和其他字符集的源代码和注释可能成功率较低。
  • 语法错误:__ 系统可能建议修复语法不正确的代码更改,因此必须在拉取请求上运行语法检查。
  • 位置错误:__ 系统建议的修复可能是语法正确但位置错误的代码,这意味着如果用户接受修复而不编辑位置,其将引起语法错误。
  • 语义错误:__ 系统可能会建议语法有效但会更改程序语义的修复。 系统不理解程序员或代码库处理代码的意图。 具有良好的测试覆盖率有助于开发人员验证修复是否不会更改代码库的行为。
  • 安全漏洞和误导性修复:__ 系统建议的修复可能无法修正基础安全漏洞和/或引起新的安全漏洞。
  • 部分修复:__ 系统建议的修复可能仅部分解决安全漏洞,或仅部分保留预期的代码功能。 系统只能看到代码库中代码的一小部分,因此并非总是产生全局最优或正确的解决方案。

自动修复依赖项建议的限制

有时建议的修复包括代码库依赖项的更改。 如果使用依赖项管理系统,系统会自动突出显示任何更改,供开发人员查看。 在合并拉取请求之前,始终验证任何依赖项更改是否安全,并维护代码库的预期行为。

  • 新的或更新的依赖项:__ 系统可能会建议添加或更新软件依赖项作为建议修复的一部分。 例如,建议更改 JavaScript 项目的 package.json 文件以从 npm 添加依赖项。
  • 不支持或不安全的依赖项:__ 系统不知道支持或保护现有依赖项的哪些版本。
  • 捏造的依赖项:__ 系统不完全了解在更广泛的生态系统中发布的依赖项。 这可能会导致建议添加对恶意软件的新依赖项,攻击者可能会将其发布在统计上可能的依赖名称下。

减少自动修复建议的限制

减少自动修复建议限制的最佳方法是遵循最佳做法。 例如,使用 CI 测试拉取请求来验证功能要求是否不受影响,并使用依赖项管理解决方案(例如依赖项审查 API 和操作)。 有关详细信息,请参阅“关于依赖项评审”。

请务必记住,无论是同事还是自动化工具提出的建议,拉取请求的作者仍需对如何响应审查注释和建议的代码更改负责。 开发人员应始终以批判的眼光看待修改代码的建议。 如果需要,他们应编辑建议的更改,以确保生成的代码和应用程序正确、安全、满足性能条件,并满足应用程序所有其他功能和非功能要求。

后续步骤