关于 CodeQL 查询¶
CodeQL 查询用于分析代码中与安全、正确性、可维护性和可读性相关的问题。
概述¶
CodeQL 包含查询,用于查找每个支持语言中最相关和最有趣的问题。您还可以编写自定义查询以查找与您自己的项目相关的特定问题。重要的查询类型是
- **警报查询**:突出显示代码中特定位置问题的查询。
- **路径查询**:描述代码中源和接收器之间信息流的查询。
您可以将自定义查询添加到 CodeQL 包 中,以使用“代码扫描”分析您的项目,使用它们来分析使用“CodeQL CLI”的数据库,或者您可以为我们 GitHub 上的开源仓库 中的标准 CodeQL 查询做出贡献。
本主题是对查询文件的简要介绍。您可以在“CodeQL 语言指南”中找到有关为特定编程语言编写查询的更多信息,以及在“QL 语言参考”中找到有关 QL 的详细技术信息。有关在将查询贡献到 GitHub 仓库时如何格式化代码的更多信息,请参阅 CodeQL 样式指南。
基本查询结构¶
使用 CodeQL 编写的查询 的文件扩展名为 .ql
,并且包含一个 select
子句。许多现有查询包含其他可选信息,并且具有以下结构
/**
*
* Query metadata
*
*/
import /* ... CodeQL libraries or modules ... */
/* ... Optional, define CodeQL classes and predicates ... */
from /* ... variable declarations ... */
where /* ... logical formula ... */
select /* ... expressions ... */
以下部分描述了通常包含在警报查询文件中的信息。路径查询在“创建路径查询”中进行了更详细的讨论。
查询元数据¶
查询元数据用于在将您的自定义查询添加到 GitHub 仓库或用于分析时标识它们。元数据提供了有关查询目的的信息,还指定了如何解释和显示查询结果。有关元数据属性的完整列表,请参阅“CodeQL 查询的元数据”。确切的元数据要求取决于您将如何运行查询
- 如果您要将查询贡献到 GitHub 仓库,请阅读 查询元数据样式指南。
- 如果您使用 CodeQL CLI 分析数据库,则您的查询元数据必须包含
@kind
。 - 如果您使用适用于 VS Code 的 CodeQL 扩展运行查询,则元数据不是必需的。但是,如果您希望将您的结果显示为“警报”或“路径”,则必须指定正确的
@kind
属性,如下所述。有关更多信息,请参阅 GitHub 文档中的 运行 CodeQL 查询。
注意
贡献到开源仓库的查询,或者用于使用 CodeQL CLI 分析数据库的查询必须指定查询类型 (
@kind
)。@kind
属性指示如何解释和显示查询分析的结果
- 警报查询元数据必须包含
@kind problem
,以将结果标识为简单警报。- 路径查询元数据必须包含
@kind path-problem
,以将结果标识为由代码位置序列记录的警报。- 诊断查询元数据必须包含
@kind diagnostic
,以将结果标识为有关提取过程的故障排除数据。- 摘要查询元数据必须包含
@kind metric
和@tags summary
,以将结果标识为 CodeQL 数据库的摘要指标。当您定义自定义查询的
@kind
属性时,您还必须确保查询的其余部分具有正确的结构才能有效,如下所述。
导入语句¶
每个查询通常包含一个或多个 import
语句,这些语句定义要导入查询的库 或模块。库和模块提供了一种将相关类型、谓词和其他模块组合在一起的方法。然后,查询可以访问您导入的每个库或模块的内容。我们 GitHub 上的开源仓库 包含每个支持语言的标准 CodeQL 库。
在编写您自己的警报查询时,您通常会导入您要查询的项目的语言的标准库。有关导入标准 CodeQL 库的更多信息,请参阅 CodeQL 库指南
- 适用于 C 和 C++ 的 CodeQL 库指南
- 适用于 C# 的 CodeQL 库指南
- 适用于 Go 的 CodeQL 库指南
- 适用于 Java 和 Kotlin 的 CodeQL 库指南
- 适用于 JavaScript 的 CodeQL 库指南
- 适用于 Python 的 CodeQL 库指南
- 适用于 Ruby 的 CodeQL 库指南
- 适用于 TypeScript 的 CodeQL 库指南
还有一些库包含与不同分析相关的常用谓词、类型和其他模块,包括数据流、控制流和污点跟踪。为了计算路径图,路径查询要求您将数据流库导入查询文件。有关更多信息,请参阅“创建路径查询。”
您可以浏览 CodeQL 库参考文档 或 GitHub 仓库 中所有标准库的内容。
from 子句¶
from
子句声明查询中使用的变量。每个声明必须采用 <type> <variable name>
的形式。有关可用类型 的更多信息,以及了解如何使用类 定义您自己的类型,请参阅 QL 语言参考。
where 子句¶
where
子句定义要应用于 from
子句中声明的变量的逻辑条件,以生成您的结果。此子句使用聚合、谓词 和逻辑公式 将感兴趣的变量限制为更小的集合,这些集合满足定义的条件。CodeQL 库将特定语言和框架的常用谓词分组在一起。您也可以在查询文件的主体或您自己的自定义模块中定义自己的谓词,如上所述。
select 子句¶
select
子句指定要为满足 where
子句中定义的条件的变量显示的结果。select 子句的有效结构由元数据中指定的 @kind
属性定义。
警报查询的 select 子句 (@kind problem
) 由两列组成,具有以下结构
select element, string
element
:查询识别的代码元素,定义了警报显示的位置。string
:消息,其中可能还包括链接和占位符,解释了为什么生成了警报。
您可以修改 select
语句最后列中定义的警报消息,以使用链接和占位符提供有关查询找到的警报或路径的更多详细信息。有关更多信息,请参阅“定义查询结果。”
路径查询的 select 子句 (@kind path-problem
) 用于显示警报以及关联路径图的源和接收器。有关更多信息,请参阅“创建路径查询。”
诊断查询 (@kind diagnostic
) 和摘要指标查询 (@kind metric
和 @tags summary
) 的 select 子句有不同的要求。有关示例,请参阅 CodeQL 仓库中的 诊断查询 和 摘要指标查询。
查看标准 CodeQL 查询¶
编写自己的查询最简单的方法之一是修改现有查询。要查看标准 CodeQL 查询或尝试其他示例,请访问 GitHub 上的 CodeQL 存储库。
您还可以找到在 GitHub 安全实验室网站 和相关 存储库 中开发的用于查找开源软件项目中安全漏洞和错误的查询示例。