关于 Copilot Autofix for code scanning
GitHub Copilot Autofix 是代码扫描的扩展,它为用户提供有针对性的建议,以帮助他们修复代码扫描警报,从而避免引入新的安全漏洞。潜在的修复是由大型语言模型 (LLM) 使用代码库和代码扫描分析中的数据自动生成的。GitHub Copilot Autofix 可用于 CodeQL 分析,并支持第三方工具 ESLint(第三方支持处于公开预览阶段,可能随时更改)。
注意
您无需订阅 GitHub Copilot 即可使用 GitHub Copilot Autofix。Copilot Autofix 可用于 GitHub.com 上的所有公共存储库,以及已获得 GitHub 高级安全许可证的 GitHub Enterprise Cloud 企业中的私有存储库。
Copilot Autofix 生成与现有源代码相关的潜在修复,并将警报的描述和位置转换为可能修复警报的代码更改。Copilot Autofix 使用与来自 OpenAI 的大型语言模型 GPT-4o 交互的内部 GitHub Copilot API,该模型具有足够的生成能力来生成代码中的建议修复以及这些修复的解释性文本。
默认情况下允许并为每个使用 CodeQL 的存储库启用 Copilot Autofix,但您可以选择退出并禁用 Copilot Autofix。要了解如何在企业、组织和存储库级别禁用 Copilot Autofix,请参阅“禁用代码扫描的 Copilot Autofix”。
在组织的安全概述仪表板中,您可以查看在给定时间段内在组织中针对打开和关闭的拉取请求生成的代码建议总数。有关更多信息,请参阅 GitHub Enterprise Cloud 文档中的“查看安全见解”。
开发人员体验
代码扫描用户已经可以查看安全警报以分析其拉取请求。但是,开发人员通常在代码安全方面接受的培训很少,因此修复这些警报需要大量工作。他们必须首先阅读并理解警报位置和描述,然后利用这种理解来编辑源代码以修复漏洞。
Copilot Autofix 通过将最佳实践信息与代码库和警报的详细信息相结合,向开发人员建议潜在的修复,从而降低了开发人员的入门门槛。开发人员无需从搜索有关漏洞的信息开始,而是从演示其代码库潜在解决方案的代码建议开始。开发人员评估潜在的修复以确定它是否是其代码库的最佳解决方案,并确保它保持预期的行为。
提交建议的修复或修改后的修复后,开发人员应始终验证代码库的持续集成测试 (CI) 是否继续通过以及警报是否显示为已解决,然后再合并其拉取请求。
CodeQL 代码扫描支持的语言
Copilot Autofix 支持为 C#、C/C++、Go、Java/Kotlin、Swift、JavaScript/TypeScript、Python 和 Ruby 的默认和安全扩展 CodeQL 查询套件中包含的一部分查询生成修复。有关这些查询套件的更多信息,请参阅“CodeQL 查询套件”。
建议生成过程
当为存储库启用 Copilot Autofix 时,识别的代码扫描警报会将输入发送到 LLM。如果 LLM 可以生成潜在的修复,则该修复将显示为建议。
GitHub 将来自代码扫描分析的各种数据发送到 LLM。例如
- SARIF 格式的 CodeQL 警报数据。有关更多信息,请参阅“代码扫描的 SARIF 支持”。
- 来自分支当前版本的代码。
- 每个源位置、接收器位置以及警报消息中引用的任何位置或流程路径中包含的任何位置周围的简短代码片段。
- 每个参与上述任何位置的文件中的前约 10 行。
- 识别问题的 CodeQL 查询的帮助文本。例如,请参阅“CodeQL 查询帮助”。
任何 Copilot 自动修复建议都会在代码扫描后端生成和存储。它们显示为建议。除了在代码库上启用代码扫描和创建拉取请求之外,不需要任何用户交互。
生成修复的过程不会收集或利用超出上述范围的任何客户数据。因此,此功能的使用受与 GitHub 高级安全相关的现有条款和条件的约束。此外,Copilot 自动修复处理的数据严格不用于 LLM 训练目的。有关 GitHub 高级安全条款和条件的更多信息,请参阅“GitHub 附加产品和功能条款”。
建议的质量
GitHub 使用自动测试工具持续监控 Copilot 自动修复建议的质量。这使我们能够了解 LLM 生成的建议在模型开发过程中如何变化。
测试工具包含来自各种公共存储库的 2300 多个警报,其中突出显示的代码具有测试覆盖率。测试这些警报的建议以查看它们的质量,即开发人员在将其提交到代码库之前需要对其进行多少编辑。对于许多测试警报,LLM 生成的建议可以按原样提交以修复警报,同时继续成功通过所有现有的 CI 测试。
此外,系统还进行了压力测试以检查任何潜在的危害(通常称为红队),并且 LLM 上的过滤系统有助于防止潜在的有害建议显示给用户。
GitHub 如何测试建议
我们通过在运行代码扫描和存储库的单元测试之前合并所有建议的更改(未经编辑)来测试建议的有效性。
- 建议是否修复了代码扫描警报?
- 修复是否引入了任何新的代码扫描警报?
- 修复是否引入了代码扫描可以检测到的任何语法错误?
- 修复是否更改了任何存储库测试的输出?
此外,我们还抽查了许多成功的建议,并验证它们是否在不引入新问题的情况下修复了警报。当其中一项或多项检查失败时,我们的手动分类显示,在许多情况下,建议的修复几乎是正确的,但需要用户可以识别并手动执行的一些小修改。
对其他项目的有效性
测试集包含各种类型的项目和警报。我们预测,使用 Copilot 自动修复支持的语言的其他项目的建议应该遵循类似的模式。
- Copilot 自动修复可能会为大多数警报添加代码建议。
- 当开发人员评估建议时,我们预计大多数修复可以在不进行编辑或进行少量更新以反映代码的更广泛上下文的情况下提交。
- 一小部分建议的修复将反映对代码库或漏洞的重大误解。
但是,每个项目和代码库都是独一无二的,因此开发人员可能需要在提交之前编辑更大比例的建议修复。Copilot 自动修复提供了有价值的信息来帮助您解决代码扫描警报,但最终,您仍有责任评估建议的更改并确保代码的安全性和准确性。
注意
支持语言的修复生成受 LLM 操作能力的限制。此外,每个建议的修复在添加到拉取请求之前都会进行测试。如果没有任何建议可用,或者如果建议的修复未能通过内部测试,则不会显示任何建议。
建议的局限性
当您查看来自 Copilot 自动修复的建议时,您必须始终考虑 AI 的局限性,并在接受更改之前根据需要编辑更改。您还应该考虑在为代码扫描启用 Copilot 自动修复之前更新存储库的 CI 测试和依赖项管理。有关更多信息,请参阅“缓解建议的局限性”。
代码建议的局限性
- 人类语言:该系统主要使用英语数据,包括发送到系统的提示、LLM 在其数据集中看到的代码以及用于内部评估的测试用例。对于使用其他语言和字符集编写的源代码和注释,LLM 生成的建议可能成功率较低。
- 语法错误:该系统可能会建议并非语法正确的代码更改的修复,因此在拉取请求上运行语法检查非常重要。
- 位置错误:该系统可能会建议语法正确的代码修复,但建议的位置不正确,这意味着如果用户在不编辑位置的情况下接受修复,则会引入语法错误。
- 语义错误:该系统可能会建议语法有效但会更改程序语义的修复。该系统不了解程序员或代码库在代码应如何运行方面的意图。拥有良好的测试覆盖率可以帮助开发人员验证修复不会更改代码库的行为。
- 安全漏洞和误导性修复:该系统可能会建议无法修复根本安全漏洞和/或引入新的安全漏洞的修复。
- 部分修复:该系统可能会建议仅部分解决安全漏洞或仅部分保留预期代码功能的修复。该系统仅查看代码库中的一小部分代码,并不总是产生全局最优或正确的解决方案。
依赖项建议的局限性
有时建议的修复包括更改代码库的依赖项。如果您使用依赖项管理系统,则任何更改都会自动突出显示供开发人员查看。在合并拉取请求之前,始终验证任何依赖项更改是否安全并保持代码库的预期行为。
- 新的或更新的依赖项:该系统可能会建议作为建议的修复的一部分添加或更新软件依赖项。例如,通过建议更改 JavaScript 项目的
package.json
文件以添加来自 npm 的依赖项。 - 不受支持或不安全的依赖项:该系统不知道现有依赖项的哪些版本受支持或安全。
- 伪造的依赖项:该系统对更广泛生态系统中发布的依赖项的了解不完整。这可能导致建议添加对攻击者以统计上可能的依赖项名称发布的恶意软件的新依赖项。
缓解建议的局限性
缓解 Copilot 自动修复建议的局限性的最佳方法是遵循最佳实践。例如,使用 CI 测试拉取请求以验证功能需求不受影响,并使用依赖项管理解决方案,例如依赖项审查 API 和操作。有关更多信息,请参阅“关于依赖项审查”。
重要的是要记住,拉取请求的作者对他们如何响应审查评论和建议的代码更改负有责任,无论是同事还是自动化工具提出的。开发人员应始终批判性地看待代码更改建议。如有必要,他们应编辑建议的更改,以确保生成的代码和应用程序是正确的、安全的、满足性能标准,并满足应用程序的所有其他功能和非功能需求。
注意
如果您是 PR 的 Copilot 工作区的公开预览版用户,则可以点击拉取请求中的 Copilot 自动修复建议上的**在工作区中打开**,直接在 GitHub 上打开 Copilot 工作区。PR 的 Copilot 工作区允许您查看和编辑所有 Copilot 自动修复建议和其他审查建议,运行 CI 测试以确认它们仍然通过,然后在一个提交中应用多个更改。有关更多信息,请参阅“使用 Copilot 帮助您处理拉取请求”。