简介
前面两篇文章已经介绍了codeql的常规用法了,可以说大概够用了,但是其中用了很多内置的函数,全靠注释和猜测去判断其功能,为了以后能深入codeql,还是啃一遍官方文档吧,查漏补缺。
官方文档地址:https://codeql.github.com/docs/
概述
CodeQL分析步骤
主要有3步:
- 准备分析的代码,创建codeql数据库(收集有关源代码的所有相关信息,包括抽象语法树(Abstract Syntax Tree)的语法数据和名称绑定、类型信息的语义数据)
- 编写QL规则进行数据库查询(CodeQL 查询是用一种专门设计的面向对象的查询语言编写的,称为 QL)
- 解释查询结果
支持的语言和框架
https://codeql.github.com/docs/codeql-overview/supported-languages-and-frameworks/
codeql规则准备
codeql自带了很多的ql规则,可以直接从github仓库clone
- 包含基础QL示例和大量QL规则的仓库(vscode推荐)
git clone https://github.com/github/vscode-codeql-starter.git
cd vscode-codeql-starter
git submodule update --init --remote
# 更新子模块
git submodule update --remote
- 只有大量规则的仓库
git clone https://github.com/github/codeql.git
VSCode上codeql插件使用技巧
获取数据库
可以用codeql database create
生成,也可以直接从LGTM.com下载
运行多个查询
给ql
规则文件夹添加到工作区中,然后多选ql文件,右键最下面就可以同时运行多个规则
比较两次结果的差异
抽象语法树(AST)
对着文件点击右键,然后view ast即可
CodeQL CLI 手册
QL语法
语法结构
使用CodeQL编写的查询具有文件扩展名.ql
,并包含一个select
子句。许多现有查询包括额外的可选信息,并具有以下结构:
/**
*
* Query metadata
*
*/
import /* ... CodeQL libraries or modules ... */
/* ... Optional, define CodeQL classes and predicates ... */
from /* ... variable declarations ... */
where /* ... logical formula ... */
select /* ... expressions ... */
查询元数据
和普通的注释不完全一样,在有些情况下,元数据是必须的,比如用于导出报告的时候
元数据指南:
- https://github.com/github/codeql/blob/main/docs/query-metadata-style-guide.md
- https://codeql.github.com/docs/writing-codeql-queries/metadata-for-codeql-queries/
建议直接拿官方的ql文件改,可以省不少时间
导入语句
每个查询通常包含一个或多个import
语句,这些语句定义要导入查询的库或模块。库和模块提供了一种将相关类型、谓词和其他模块组合在一起的方法。
不同语言导入的库
- C/C++:
cpp
- C#:
csharp
- Go:
go
- Java:
java
- JavaScript/TypeScript:
javascript
- Python:
python
// 从标准 CodeQL 库中导入的路径图模块
import DataFlow::PathGraph
可选的类和谓词
这部分内容不是必须的,属于可有可无的情况,就类似代码中的函数一样,可以单独抽象到类中,也可以全部写到主函数
from
from
子句声明查询中使用的变量,一般格式为
from <type> <variable name>
from Parameter p
where
有点类似if语句,后面接判定条件的,要求判定条件的结果为true
where not exists(p.getAnAccess())
在审计的时候通过hasFlowPath
来判断source和sink的连通性
where config.hasFlowPath(source, sink)
select
和sql中的select差不多,选择输出语句,输出结果,$@
表示占位符
select p
alert
查询
select element, string
element
:由查询标识的代码元素,它定义了alert
的显示位置。string
:一条消息,还可以包括链接和占位符,解释生成alert
的原因。
select element, source, sink, string
QL教程
下面有很多学习用的例子,主要讲解了基础的语法,比如谓词(函数)、逻辑连接符(and or)、创建类、递归
下面是针对一些语言的实例和说明,比如为什么要写import java
比较完整的QL规则
QL标准库
经常看到调用了很多的谓词,比如getAnAccess()
、hasName()
,又不太明确啥意思,可以直接看注释,获取去下面的标准库链接中查询