8.1.2 CodeQL概述
最后更新于:2022-04-02 07:46:23
### 以下内容来自官方文档
#### **1. 软件架构和关系**
**1. 1 CodeQL能干什么?**
> GitHub出品,codeql.github.com。CodeQL是语义代码分析引擎,可以像查询数据库一样查询代码,编写查询以查找漏洞的《所有变体》,从而消除它,分享查询也可以帮助别人这样做。tip:也可以用别人的查询帮助自己。
> 使用LGTM.com上的CodeQL查询控制台,对流行的开源代码库运行实际查询。tip:用github代码演练
**1.2 什么是LGTM?**
> 用户查找0day漏洞和放置关键漏洞的代码分析平台,对开源项目是完全免费的
#### **2. 技术细节**
**CodeQL**
> 在CodeQL中,代码被视为数据。安全漏洞、错误和其他错误被《建模》,可以针对从代码中提取的数据库执行查询,可以运行标准查询也可以自定义分析。
**变异分析**
> 变体分析是使用一直的安全漏洞作为种子,在代码中发现类似问题的过程,使用CodeQL查询代码是执行变体分析的最有效方式。可以使用CodeQL查询来识别种子漏洞,或通过编写自定义的CodeQL查询来查找新漏洞。然后开发和迭代查询,以自动查找传统手动技术可能遗漏的同一错误逻辑变体。
2.1 支持的语言和框架
[CodeQL 支持的语言和框架](https://codeql.github.com/docs/codeql-overview/supported-languages-and-frameworks/)
2.2 CodeQL工具
> GitHub提供了CodeQL命令行接口和 基于VS Code的CodeQL插件,用于在开源代码库上执行CodeQL分析。
CLI
> CodeQL命令行接口主要用于创建用户安全研究的数据库。您可以直接从命令行或使用VS Code扩展查询CodeQL数据库。
VC Code扩展
> 使用VS Code扩展分析CodeQL数据库,该扩展为编写和用户自定义查询以及查看结果提供了增强的环境。
#### **3. CodeQL分析的三个步骤**
> 1. 准备代码,通过CodeQL创建数据库
> 2. 对数据库运行CodeQL查询
> 3. 解释查询结果
**3.1 数据库创建**
> 为了创建数据库,CodeQL首先提取代码库中每个源文件的单个关系表示
对于编译语言
> 通过监视正常的构建过程来工作。每次调用编译器来处理源文件是,都会制作该文件的副本,并收集有关源代码的所有相关信息。这包括有关抽象语法书的句法数据和有关名称绑定和类型信息的语义数据。
对于解释语言
> 提取器直接在元马上运行,解析依赖关系以提供代码库的准确表示。
> CodeQL支持的每种语言都有一个提取器,以确保提取过程尽可能准确。对于多语言代码库,数据库一次生成一种语言。
> 提取后,分析所需要的所有数据(关系数据、复制的源文件和特定语言的数据库模式,它指定数据中的相互关系),被导入到一个目录中,称为CodeQL数据库
> tip: 基于语义与句法的Java类库检索方法与系统。
**3.2 查询结果**
> 最后一步将查询执行期间产生的结果转换为源代码上下文中更有意义的形式。也就是说,结果的解释方式突出了查询旨在发现的潜在问题。
> 查询包括指示应如何解释结果的元数据属性。例如,某些查询在代码中的单个位置显示为一条简单的消息。其他则显示一系列代表数据流或控制流路径上的步骤的位置,以及解释结果重要性的消息。没有元数据的查询不会被解释——他们的结果作为表格数据而不显示在源代码中。
> Question:数据流、控制流是什么?
> 在解释后,结果被输出用于代码审查和分类。在CodeQL for Visual Studio Code中,解释的查询会自动显示在源代码中。CodeQL CLI生成的结果可以输出为多种不同格式,以供不同工具使用。
#### **4. CodeQL packs和QL packs区别**
> CodeQL包:CodeQL包《**使用CodeQL CLI创建的**》,用于创建、依赖、发布和运行CodeQL查询和库。
> QL包: QL包用于《**组织**》CodeQL分析中使用的文件。他们包括查询、库文件、查询套件和重要元数据。
**4.1 关于CodeQL packs**
> CodeQL包管理(新项目,和CodeQL不同)功能目前为测试版本提供,Beta版本期间使仅可以使用GitHub
> CodeQL包用户创建、共享、依赖和运行CodeQL查询和库,可以发布自己的CodeQL包,也可以下载他人创建的包。CodeQL包包含查询、库文件、查询套件和元数据。
> CodeQL包有两种类型:查询包和库包
> 查询旨在运行。打不查询包时,该包包含所有传递依赖项和编译缓存。这确保保重查询的一致和高效执行
> 库包旨在提供查询宝(或其他库包)使用,并不包含查询本身。库未编译,并且在发布包时不包含编译缓存
> 可以使用CodeQL CLI中的包管理命令来创建CodeQL包、向包添加依赖项以及安装或更新依赖项。
CodeQL包结构
> CodeQL包必须在其根目录包含一个《qlpack.yml》的文件。在qlpack.yml文件中,name:字段的值必须遵循/格式,其中是发布包的GitHub《组织或者用户账户》,是包的名称。包中的其他文件和目录应该着逻辑组织,通常:
> 1. 查询被组织到特定类别的目录中
> 2. 对特定产品、库和框架的查询被组织到他们自己的顶级目录中
关于CodeQL的qlpack.yml文件
> 再执行与查询相关的命令式,CodeQL受限再安装目录(及其子目录)的兄弟目录中查找qlpack.yml文件。然后他会检查已下载的CodeQL包的宝缓存。这意味着当再本地开发查询时,安装目录中的本地包会覆盖包缓存中的通明白,以便可以测试本地更改。tip: 安装目录查看8.1.4章节
> 每个qlpack.yml文件中的元数据告诉CodeQL如何编译保重的任何查询、包依赖的库以及在哪可以查询套件定义。
> **CodeQL包的内容(CodeQL分析使用的查询或库)包含在与qlpack.yml相同的目录或其子目录中**
> qlpack.yml的位置定义了CodeQL包内容的库路径。也就是说,对于包中的所有.ql和.qll文件,CodeQL将解析与包根目录下的qlpack.yml相关的所有导入语句
[About CodeQL packs 配置选项](https://codeql.github.com/docs/codeql-cli/about-codeql-packs/)
#### 关于QL packs
> QL包用于组织CodeQL分析中使用的文件。他们包含查询、库文件、查询套件和重要的元数据。
> CodeQL存储库包含C/C++、C#、Java、JavaScript、Python和Ruby的QL包。CodeQL for Go存储库包含用户Go分析的QL包。还可以制作自定义QL包以包含自定义查询和库。
**4.2 QL包结构**
> QL包必须在其根目录包含一个名为qlpack.yml的文件。包中的其他文件和目录应该按逻辑组织。通常:
> 1. 查询被组织到特定类别的目录中
> 2. 对特定茶品、库、和框架的查询被组织到他们自己的顶级目录中。
> 3. 查询库(.qll)文件有一个名为/的顶级目录。此目录中,.qll文件硬组织到特定类别的子目录中
关于QL包中的qlpack.yml文件
> 再执行命令时,CodeQL会扫描安装目录(及子目录)的兄弟目录中的qlpack.yml文件。文件中的元数据告诉CodeQL如何编译查询、包依赖的库以及在哪里可以找到查询套件定义。
> QL包的内容(CodeQL分析中使用的查询和库)与qlpack.yml或其子目录包含在同一目录中。
> qlpack.yml的位置定义了QL包内容的库路径。也就是说,对于QL包中的所有.ql和.qll文件,CodeQL将解析与包根目录下的qlpack.yml相关的所有导入语句。
> 例如在包含以下内容的QL包中,可以通过声明import mycompany.java.CustomSinks从包中的任何位置导入CustomSinks.qll
```
qlpack.yml
mycompany/
java/
security/
CustomSinks.qll
Security/
CustomQuery.ql
```
#### **Question: 自定义QL包**
';