CodeQL 创建路径查询
创建路径查询
官方文档:Creating path queries — CodeQL (github.com)
概览
安全研究人员对程序中信息流动的方式特别感兴趣。许多漏洞是由看似良性的数据流向意外位置并被恶意使用而引起的。使用 CodeQL 编写的路径查询对于分析数据流特别有用,因为它们可用于跟踪变量从可能的起点(源)到可能的终点(接收器)的路径。要对路径建模,查询必须提供有关源和接收器的信息,以及链接它们的数据流步骤。
本主题提供有关如何构造路径查询文件的信息,以便您可以探索与数据流分析结果相关联的路径。
注意
路径查询生成的警报默认显示在 LGTM 中,并包含在使用 CodeQL CLI 生成的结果中。您还可以直接在 LGTM 或 VS 代码的 CodeQL 扩展中查看路径查询生成的路径解释。
要了解有关使用 CodeQL 建模数据流的更多信息,请参见“关于数据流分析”有关分析数据流的更多特定于语言的信息,请参见:
- “ C/c + + 中的数据流分析”
- “ C # 中数据流的分析”
- “ 分析 Java 中的数据流”
- “ 分析 JavaScript/TypeScript 中的数据流”
- “ 分析 Python 中的数据流”
路径查询示例
开始编写自己的路径查询的最简单方法是修改一个现有的查询。有关详细信息,请参阅 CodeQL query help.。
安全实验室的研究人员已经使用路径查询来发现各种开源项目中的安全漏洞。要查看描述这些查询是如何编写的文章,以及其他描述安全研究其他方面的文章,如利用漏洞,请查看 GitHub Security Lab website.
构造路径查询
路径查询需要某些元数据、查询谓词和选择语句结构。CodeQL 中包含的许多内置路径查询遵循一个简单的结构,这取决于如何使用 CodeQL 对所分析的语言进行建模。
你应该使用以下模板:
/**
* ...
* @kind path-problem
* ...
*/
import <language>
// For some languages (Java/C++/Python) you need to explicitly import the data flow library, such as
// import semmle.code.java.dataflow.DataFlow
import DataFlow::PathGraph
...
from MyConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "<message>"
DataFlow::Pathgraph
:从标准 CodeQL 库导入的路径图模块source
及sink
是路径图上的节点 ,DataFlow::PathNode
是它们的类型。MyConfiguration
是一个包含谓词的类,这些谓词定义了数据如何在源
和汇
之间流动。
以下部分描述有效路径查询的主要需求。
路径查询元数据
路径查询元数据必须包含属性@kind Path-problem-
这可以确保查询结果被正确解释和显示。其他元数据要求取决于您打算如何运行查询。有关更多信息,请参见“ CodeQL 查询的元数据”
生成路径解释
为了生成路径解释,查询需要计算路径图。为此,您需要在查询中定义一个称为边的查询谓词。这个谓词定义了要计算的图的边关系,并用于计算与查询生成的每个结果相关的路径。可以从标准数据流库之一的路径图模块中导入预定义的边谓词。
除了路径图模块之外,数据流库还包含数据流分析中常用的其他类、谓词和模块。
import DataFlow::PathGraph
该语句从数据流库(DataFlow.qll)
导入 PathGraph
模块,其中定义了edges
边。
您还可以导入专门为在各种常见框架和环境中实现数据流分析而设计的库,并且 CodeQL 还包含许多其他库。要查看数据流分析中使用的不同库的示例,请参阅上面内置查询的链接或浏览标准库。
定义自己的边谓词
query predicate edges(PathNode a, PathNode b) {
/** Logical conditions which hold if `(a,b)` is an edge in the data flow graph */
}
For more examples of how to define an edges
predicate, visit the standard CodeQL libraries and search for edges
.
有关如何定义边缘谓词的更多示例,请访问标准 CodeQL 库并搜索边缘。
声明sources and sinks
from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
通过导入数据流库来访问配置类。此类包含定义如何在查询中处理数据流的谓词:
isSource()
defines where data may flow from.isSink()
defines where data may flow to.
还可以通过扩展 Configuration 类为不同的框架和环境创建配置。有关更多信息,请参见 QL 语言参考中的“类型”。
定义flow conditions
where config.hasFlowPath(source, sink)
Select clause
select element, source, sink, string
element和string分别代码告警的位置和告警的消息。
source和sink是路径图中节点。
element列可以使用source或者sink,这取决于你的需求。