CodeQL规则编写之常用类与特殊情况
字数 1446 2025-08-29 08:29:58

CodeQL规则编写之常用类与特殊情况

前言

CodeQL是一种强大的代码分析工具,能够帮助开发者发现代码中的潜在问题。在编写CodeQL规则时,理解其Java类库的结构和功能至关重要。

Codeql中的Java类库

CodeQL提供了丰富的Java类库用于分析Java代码,这些类库构成了编写规则的基础。

常用类及谓词

1、Expr类

Expr类表示Java中的表达式,是所有表达式的基类。常用谓词包括:

  • getType(): 获取表达式的类型
  • getAChildExpr(): 获取子表达式
  • getParent(): 获取父节点

2、Variable类

Variable类表示变量声明,包括局部变量、参数和字段。常用谓词:

  • getAnAccess(): 获取变量的访问点
  • getType(): 获取变量类型
  • getName(): 获取变量名

3、Annotation类

Annotation类处理Java注解。常用谓词:

  • getType(): 获取注解类型
  • getValue(String name): 获取注解的特定属性值

4、Callable类

Callable表示可调用的实体,包括方法和构造函数。常用谓词:

  • getName(): 获取名称
  • getNumberOfParameters(): 获取参数数量
  • getParameter(int n): 获取特定参数

5、Call类

Call类表示方法调用。常用谓词:

  • getCallee(): 获取被调用的方法
  • getArgument(int n): 获取特定参数
  • getQualifier(): 获取调用限定符

6、MethodCall类

MethodCall是Call的子类,专门表示方法调用。常用谓词:

  • getMethod(): 获取被调用的方法

7、ConstructorCall类

ConstructorCall是Call的子类,表示构造函数调用。常用谓词:

  • getConstructor(): 获取被调用的构造函数

常见的特殊情况

全版本通用情况

一、第三方包调用

  1. 传播到第三方包的参与函数调用

    • 需要特别处理跨包的数据流
    • 使用TaintTracking时要考虑包边界
  2. 传播到第三方包的类中进行实例化

    • 需要识别第三方包的工厂模式
    • 可能需要自定义数据流步骤

二、fastjson

  • 需要特殊处理反序列化路径
  • 关注parseObjectparse方法的调用
  • 注意自动类型推断可能导致的安全问题

三、HashMap问题

  • 需要识别HashMapputget操作
  • 注意键值对中可能包含污染数据
  • 特别关注自定义hashCodeequals方法的影响

历史版本存在的情况

一、Lombok问题

  • Lombok生成的代码需要特殊处理
  • 可能需要识别@Data@Getter等注解
  • 数据流分析要考虑生成的代码

二、配置文件问题

  1. pre-finalize

    • 处理配置文件的特殊生命周期
    • 需要识别配置加载和使用的时机
  2. 环境变量 LGTM_INDEX_XML_MODE

    • 影响XML文件的解析方式
    • 可能需要根据环境调整分析策略
  3. 打包指定格式的文件

    • 需要识别特定格式的资源文件
    • 可能需要自定义文件解析逻辑

总结

编写有效的CodeQL规则需要深入理解其类库结构,并能够处理各种特殊情况。掌握这些常用类和特殊情况处理方法,可以显著提高规则的质量和准确性。

CodeQL规则编写之常用类与特殊情况 前言 CodeQL是一种强大的代码分析工具,能够帮助开发者发现代码中的潜在问题。在编写CodeQL规则时,理解其Java类库的结构和功能至关重要。 Codeql中的Java类库 CodeQL提供了丰富的Java类库用于分析Java代码,这些类库构成了编写规则的基础。 常用类及谓词 1、Expr类 Expr类表示Java中的表达式,是所有表达式的基类。常用谓词包括: getType() : 获取表达式的类型 getAChildExpr() : 获取子表达式 getParent() : 获取父节点 2、Variable类 Variable类表示变量声明,包括局部变量、参数和字段。常用谓词: getAnAccess() : 获取变量的访问点 getType() : 获取变量类型 getName() : 获取变量名 3、Annotation类 Annotation类处理Java注解。常用谓词: getType() : 获取注解类型 getValue(String name) : 获取注解的特定属性值 4、Callable类 Callable表示可调用的实体,包括方法和构造函数。常用谓词: getName() : 获取名称 getNumberOfParameters() : 获取参数数量 getParameter(int n) : 获取特定参数 5、Call类 Call类表示方法调用。常用谓词: getCallee() : 获取被调用的方法 getArgument(int n) : 获取特定参数 getQualifier() : 获取调用限定符 6、MethodCall类 MethodCall是Call的子类,专门表示方法调用。常用谓词: getMethod() : 获取被调用的方法 7、ConstructorCall类 ConstructorCall是Call的子类,表示构造函数调用。常用谓词: getConstructor() : 获取被调用的构造函数 常见的特殊情况 全版本通用情况 一、第三方包调用 传播到第三方包的参与函数调用 : 需要特别处理跨包的数据流 使用 TaintTracking 时要考虑包边界 传播到第三方包的类中进行实例化 : 需要识别第三方包的工厂模式 可能需要自定义数据流步骤 二、fastjson 需要特殊处理反序列化路径 关注 parseObject 和 parse 方法的调用 注意自动类型推断可能导致的安全问题 三、HashMap问题 需要识别 HashMap 的 put 和 get 操作 注意键值对中可能包含污染数据 特别关注自定义 hashCode 和 equals 方法的影响 历史版本存在的情况 一、Lombok问题 Lombok生成的代码需要特殊处理 可能需要识别 @Data 、 @Getter 等注解 数据流分析要考虑生成的代码 二、配置文件问题 pre-finalize : 处理配置文件的特殊生命周期 需要识别配置加载和使用的时机 环境变量 LGTM_ INDEX_ XML_ MODE : 影响XML文件的解析方式 可能需要根据环境调整分析策略 打包指定格式的文件 : 需要识别特定格式的资源文件 可能需要自定义文件解析逻辑 总结 编写有效的CodeQL规则需要深入理解其类库结构,并能够处理各种特殊情况。掌握这些常用类和特殊情况处理方法,可以显著提高规则的质量和准确性。