codeql 初使用及规则分析 -
字数 1893 2025-08-10 20:57:54

CodeQL 使用指南及规则深度解析

一、CodeQL 简介

CodeQL 是 GitHub 开发的语义代码分析引擎,用于自动化安全漏洞检测。它通过将代码转换为可查询的数据库,使用类似 SQL 的查询语言来发现代码中的安全漏洞。

二、CodeQL 基础使用

1. 安装与配置

2. 创建数据库

对于 Java 项目:

codeql database create DB_DIR --language=java --command='mvn clean install'

3. 分析数据库并导出结果

两种常用输出格式:

  1. SARIF 格式(详细结果):
codeql database analyze DB_DIR --format=sarifv2.1.0 --output=/tmp/result.json codeql-main/java/ql/src/codeql-suites/java-code-scanning.qls
  1. CSV 格式(简化结果):
codeql database analyze DB_DIR --format=csv --output=/tmp/result.csv codeql-main/java/ql/src/codeql-suites/java-code-scanning.qls

4. 使用注意事项

  1. 过滤警告报告:
    修改 codeql-main/misc/suite-helpers/code-scanning-selectors.yml 文件,注释掉 problem.severity 下的 warning 部分。

  2. 启用实验性规则:

    • 实验性规则位于 codeql-main/java/ql/src/experimental 目录
    • 如 MyBatis SQL 注入规则: codeql-main/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisMapperXmlSqlInjection.ql
    • 修改 code-scanning-selectors.yml,注释掉 exclude - query path 下的 /^experimental\/.*/

三、CodeQL 规则深度解析

1. 不安全反序列化规则 (java/unsafe-deserialization)

检测原理

  • 主要检测 FastJson、XStream、Yaml 等不安全反序列化
  • 核心检测方法: unsafeDeserialization(MethodAccess ma, Expr sink)

FastJson 检测逻辑

ma.getMethod() instanceof FastJsonParseMethod 
and not fastJsonLooksSafe() 
and sink = ma.getArgument(0)

FastJson 安全模式检测

exists(FastJsonSetSafeMode setsafe | not setsafe.getMode() = false)

仅检测是否设置了 safeMode,无法检测 FastJson 版本。

改进建议

可结合 IAST 进行更精确检测,参考洞态实现:
https://github.com/HXSecurity/DongTai-agent-java

2. 路径注入规则 (java/path-injection)

规则组成

  • Source: 远程用户输入 (RemoteFlowSource)
  • Sink: 文件操作相关方法调用或实例创建
  • Sanitizer: 净化规则
  • AdditionalTaintStep: 额外污点传播步骤

Sink 定义

位于 PathCreation.qll,包含各种文件操作方法:

sink.asExpr() = any(PathCreation p).getAnInput() 
or sinkNode(sink, "create-file")

污点传播 (AdditionalTaintStep)

建立 java.net.URI 参数 path 到构造函数调用的传播:

override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
    any(TaintedPathAdditionalTaintStep s).step(n1, n2)
}

净化规则 (Sanitizer)

主要净化类型:

  1. 基本类型/包装类型/数字类型
  2. 路径相关净化器 (PathInjectionSanitizer)
PathInjectionSanitizer 子类
  1. ExactPathMatchSanitizer: 精确路径匹配检查
  2. AllowedPrefixSanitizer: 允许的前缀检查
  3. DotDotCheckSanitizer: 路径穿越检查
  4. BlockListSanitizer: 黑名单检查
ExactPathMatchSanitizer 实现
private class ExactPathMatchSanitizer extends PathInjectionSanitizer {
    ExactPathMatchSanitizer() {
        this = DataFlow::BarrierGuard<exactPathMatchGuard/3>::getABarrierNode()
        or this = ValidationMethod<exactPathMatchGuard/3>::getAValidatedNode()
    }
}
exactPathMatchGuard 定义

检测路径相关类型的精确比较:

private predicate exactPathMatchGuard(Guard g, Expr e, boolean branch) {
    exists(MethodAccess ma, RefType t |
        t instanceof TypeString or t instanceof TypeUri or t instanceof TypePath 
        or t instanceof TypeFile or t.hasQualifiedName("android.net", "Uri")
        or t instanceof StringsKt or t instanceof FilesKt |
        e = getVisualQualifier(ma).getUnderlyingExpr()
        and ma.getMethod().getDeclaringType() = t
        and ma = g
        and getSourceMethod(ma.getMethod()).hasName(["equals", "equalsIgnoreCase"])
        and branch = true
    )
}
ValidationMethod 实现
private module ValidationMethod<DataFlow::guardChecksSig/3 validationGuard> {
    DataFlow::Node getAValidatedNode() {
        exists(MethodAccess ma, int pos, RValue rv |
            validationMethod(ma.getMethod(), pos)
            and ma.getArgument(pos) = rv
            and adjacentUseUseSameVar(rv, result.asExpr())
            and ma.getBasicBlock().bbDominates(result.asExpr().getBasicBlock())
        )
    }
}

自定义净化规则示例

// 经过 FilenameUtils.getExtension 方法处理的路径认为安全
private class ExtractExtensionSanitizer extends PathInjectionSanitizer {
    ExtractExtensionSanitizer() {
        this.asExpr().(MethodAccess).getMethod().getName() = "getExtension"
        and this.asExpr().(MethodAccess).getMethod()
            .getDeclaringType().hasQualifiedName("org.apache.commons.io","FilenameUtils")
    }
}

四、高级技巧与最佳实践

  1. 规则调试: 使用 --ram=8000 参数增加内存分配
  2. 性能优化: 针对大型项目,可以分模块创建数据库
  3. 自定义规则: 继承现有规则类实现特定检测逻辑
  4. 结果验证: 结合动态测试验证静态分析结果

五、推荐阅读

  1. CodeQL数据库构建原理分析
  2. CodeQL 踩坑指南 - Java

六、总结

CodeQL 是一个强大的静态分析工具,通过深入理解其规则实现原理,可以:

  1. 更准确地识别漏洞
  2. 减少误报
  3. 针对特定项目定制检测规则
  4. 提高自动化安全检测效率

掌握 CodeQL 需要对其查询语言、Java 代码分析模型以及安全漏洞模式有深入理解,建议从实际项目入手,逐步深入。

CodeQL 使用指南及规则深度解析 一、CodeQL 简介 CodeQL 是 GitHub 开发的语义代码分析引擎,用于自动化安全漏洞检测。它通过将代码转换为可查询的数据库,使用类似 SQL 的查询语言来发现代码中的安全漏洞。 二、CodeQL 基础使用 1. 安装与配置 CodeQL CLI 下载地址: https://github.com/github/codeql-cli-binaries/releases CodeQL 规则库地址: https://github.com/github/codeql 2. 创建数据库 对于 Java 项目: 3. 分析数据库并导出结果 两种常用输出格式: SARIF 格式(详细结果): CSV 格式(简化结果): 4. 使用注意事项 过滤警告报告 : 修改 codeql-main/misc/suite-helpers/code-scanning-selectors.yml 文件,注释掉 problem.severity 下的 warning 部分。 启用实验性规则 : 实验性规则位于 codeql-main/java/ql/src/experimental 目录 如 MyBatis SQL 注入规则: codeql-main/java/ql/src/experimental/Security/CWE/CWE-089/MyBatisMapperXmlSqlInjection.ql 修改 code-scanning-selectors.yml ,注释掉 exclude - query path 下的 /^experimental\/.*/ 三、CodeQL 规则深度解析 1. 不安全反序列化规则 (java/unsafe-deserialization) 检测原理 主要检测 FastJson、XStream、Yaml 等不安全反序列化 核心检测方法: unsafeDeserialization(MethodAccess ma, Expr sink) FastJson 检测逻辑 FastJson 安全模式检测 仅检测是否设置了 safeMode ,无法检测 FastJson 版本。 改进建议 可结合 IAST 进行更精确检测,参考洞态实现: https://github.com/HXSecurity/DongTai-agent-java 2. 路径注入规则 (java/path-injection) 规则组成 Source : 远程用户输入 ( RemoteFlowSource ) Sink : 文件操作相关方法调用或实例创建 Sanitizer : 净化规则 AdditionalTaintStep : 额外污点传播步骤 Sink 定义 位于 PathCreation.qll ,包含各种文件操作方法: 污点传播 (AdditionalTaintStep) 建立 java.net.URI 参数 path 到构造函数调用的传播: 净化规则 (Sanitizer) 主要净化类型: 基本类型/包装类型/数字类型 路径相关净化器 ( PathInjectionSanitizer ) PathInjectionSanitizer 子类 ExactPathMatchSanitizer : 精确路径匹配检查 AllowedPrefixSanitizer : 允许的前缀检查 DotDotCheckSanitizer : 路径穿越检查 BlockListSanitizer : 黑名单检查 ExactPathMatchSanitizer 实现 exactPathMatchGuard 定义 检测路径相关类型的精确比较: ValidationMethod 实现 自定义净化规则示例 四、高级技巧与最佳实践 规则调试 : 使用 --ram=8000 参数增加内存分配 性能优化 : 针对大型项目,可以分模块创建数据库 自定义规则 : 继承现有规则类实现特定检测逻辑 结果验证 : 结合动态测试验证静态分析结果 五、推荐阅读 CodeQL数据库构建原理分析 CodeQL 踩坑指南 - Java 六、总结 CodeQL 是一个强大的静态分析工具,通过深入理解其规则实现原理,可以: 更准确地识别漏洞 减少误报 针对特定项目定制检测规则 提高自动化安全检测效率 掌握 CodeQL 需要对其查询语言、Java 代码分析模型以及安全漏洞模式有深入理解,建议从实际项目入手,逐步深入。