解析过程
extractor
分为两个步骤:
- 解析所有的包以及依赖的包的类型信息;
- 解析当前模块的包的AST信息
这里值得注意的是,所有的包都会解析类型信息,但是仅有当前模块的包有AST信息。缺乏AST信息, 意味着我们无法找到非当前模块的go func
等类似的语句。
DataFlow
在codeql
中,对代码的分析可大致分成两个部分,第一部分:语法分析,依赖于AST结构;第二部分,数据流分析,即go
的SSA
中间代码。
codeql-go模块
本节聚焦在go语言的分析。
codeql-go标准库:https://codeql.github.com/codeql-standard-libraries/go/
scopes定义
名称
entity.hasQaulifiedName("pkg","Name")
- 找到所有调用
net/http
包的语句:
/**
* @kind problem
*/
import go
from DataFlow::CallNode n
where n.getTarget().getQualifiedName().regexpMatch("net/http.\\w+")
select n,"call to net/http:"+n
- 找到所有含有redis包调用的方法,排除一些方法
/**
* @kind problem
*/
import go
from DataFlow::CallNode n, string qfn
where
qfn = n.getTarget().getQualifiedName() and
qfn.regexpMatch(".*redis.*") and
qfn != ["redis-v6.Cmder.String"]
select n, "call to redis:" + n + ",pkg:" + qfn
主要:这里qfn
变量是必须的,如果都是用n.getTarget().getQualifiedName()
实际上就出现笛卡尔积的情况。
表达instanceof
找到所有返回error接口及其实现类型的方法或函数:
Data-flow
https://codeql.github.com/docs/codeql-language-guides/modeling-data-flow-in-go-libraries/
术语
https://codeql.github.com/docs/codeql-overview/codeql-glossary/
-
.bqrs
文件:查询结果集的二进制表示,可以解析成展示结果 -
CodeQL数据库
:即代码解析后的数据仓库,包含可查询的数据,源文件引用,查询结果,log文件;通常是一个目录 -
DIL
:Datalog Intermediary Language
,CodeQL的查询语句被编译成Datalog
代码进行执行,可以用于分析执行的效率。你可以在VSCode的查询历史中查看DIL
-
Extractor
,从源代码中解析提取CodeQL所需数据 -
QL Database schema
: 一个描述列类型以及关系(通过关系构成原始QL数据集)的描述文件。当创建一个新的数据库时,extractor
将对应的schema
复制到数据库中,它定义了extractor
创建的数据的布局。 -
.qlo文件
: 与DIL
类似,代表了执行计划,可使用codeql query compile --dump-qlo
来输出该文件,使用codeql query decompile
来解析文件 -
SARIF文件
:Static analysis result interchange format
,是一种输出格式,用于共享静态的分析结果 -
源文件引用(Source reference)
: 可用于通过文件名来引用文件内容,被引用的文件可能来自于源代码目录
,zip归档文件
,远程git仓库
等 -
.trap文件
:UTF-8编码,由extractor
生成,为了节省空间,通常都是归档的。它们包含可用于创建QL数据集的信息,.trap
文件通常都是相对于某个QL database schema
创建的。