CodeQL静态分析Skill codeql

CodeQL是一种静态代码分析工具,专门用于安全漏洞检测、数据流分析和污点跟踪。它支持跨过程分析,帮助开发者在安全审计、CI/CD集成和自定义查询开发中发现复杂的安全问题。关键词:CodeQL、静态分析、安全漏洞、数据流、污点跟踪、安全审计、CI/CD、自定义查询。

安全审计 0 次安装 0 次浏览 更新于 3/24/2026

名称: codeql 描述: 运行CodeQL静态分析以进行安全漏洞检测、污点跟踪和数据流分析。在需要分析代码、创建CodeQL数据库、编写自定义QL查询、执行安全审计或设置CodeQL在CI/CD管道中使用。 允许的工具:

  • Bash
  • Read
  • Glob
  • Grep

CodeQL静态分析

何时使用CodeQL

理想场景:

  • 能够访问源代码并具有构建能力(对于编译语言)
  • 开源项目或GitHub高级安全许可证
  • 需要跨过程数据流和污点跟踪
  • 查找需要AST/CFG分析的复杂漏洞
  • 综合分析时间不关键的安全审计

考虑使用Semgrep的情况:

  • 编译语言没有构建能力
  • 许可证限制
  • 需要快速、轻量级的模式匹配
  • 简单的单文件分析足够

为什么跨过程分析重要

简单的grep/模式工具一次只能看到一个函数。真正的漏洞通常跨越多个函数:

HTTP处理程序 → 输入解析器 → 业务逻辑 → 数据库查询
     ↓              ↓              ↓              ↓
   源点      转换       传递       汇点 (SQL)

CodeQL跟踪所有这些步骤的数据流。处理程序中的污染输入可以通过5+个函数调用追踪到它到达危险汇点的地方。

基于模式的工具会错过这个,因为它们无法连接文件A中的request.param到文件B中的db.execute(query)

何时不使用

不要将此技能用于:

  • 无法构建的项目(CodeQL要求编译语言成功编译)
  • 快速模式搜索(使用Semgrep或grep以提高速度)
  • 非安全的代码质量检查(使用linters代替)
  • 没有源代码访问权限的项目

环境检查

# 检查CodeQL是否安装
command -v codeql >/dev/null 2>&1 && echo "CodeQL: 已安装" || echo "CodeQL: 未安装(运行下面的安装步骤)"

安装

CodeQL CLI

# macOS/Linux (Homebrew)
brew install --cask codeql

# 更新
brew upgrade codeql

手动: 从https://github.com/github/codeql-action/releases下载捆绑包

Trail of Bits查询(可选)

安装公共ToB安全查询以增加覆盖范围:

# 下载ToB查询包
codeql pack download trailofbits/cpp-queries trailofbits/go-queries

# 验证安装
codeql resolve qlpacks | grep trailofbits

核心工作流

1. 创建数据库

codeql database create codeql.db --language=<LANG> [--command='<BUILD>'] --source-root=.
语言 --language= 是否需要构建
Python python
JavaScript/TypeScript javascript
Go go
Ruby ruby
Rust rust 是 (--command='cargo build')
Java/Kotlin java 是 (--command='./gradlew build')
C/C++ cpp 是 (--command='make -j8')
C# csharp 是 (--command='dotnet build')
Swift swift 是 (仅限macOS)

2. 运行分析

# 列出可用查询包
codeql resolve qlpacks

运行安全查询:

# SARIF输出(推荐)
codeql database analyze codeql.db \
  --format=sarif-latest \
  --output=results.sarif \
  -- codeql/python-queries:codeql-suites/python-security-extended.qls

# CSV输出
codeql database analyze codeql.db \
  --format=csv \
  --output=results.csv \
  -- codeql/javascript-queries

使用Trail of Bits查询(如果已安装):

codeql database analyze codeql.db \
  --format=sarif-latest \
  --output=results.sarif \
  -- trailofbits/go-queries

编写自定义查询

查询结构

CodeQL使用类似SQL的语法: from Type x where P(x) select f(x)

基本模板

/**
 * @name 查找SQL注入漏洞
 * @description 识别来自用户输入的潜在SQL注入
 * @kind path-problem
 * @problem.severity error
 * @security-severity 9.0
 * @precision high
 * @id py/sql-injection
 * @tags security
 *       external/cwe/cwe-089
 */

import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking

module SqlInjectionConfig implements DataFlow::ConfigSig {
  predicate isSource(DataFlow::Node source) {
    // 定义污染源(用户输入)
    exists(source)
  }

  predicate isSink(DataFlow::Node sink) {
    // 定义危险汇点(SQL执行)
    exists(sink)
  }
}

module SqlInjectionFlow = TaintTracking::Global<SqlInjectionConfig>;

from SqlInjectionFlow::PathNode source, SqlInjectionFlow::PathNode sink
where SqlInjectionFlow::flowPath(source, sink)
select sink.getNode(), source, sink, "SQL注入来自 $@.", source.getNode(), "用户输入"

查询元数据

字段 描述
@kind 查询类型 problem, path-problem
@problem.severity 问题严重性 error, warning, recommendation
@security-severity CVSS分数 0.0 - 10.0
@precision 置信度 very-high, high, medium, low

关键语言特性

// 谓词
predicate isUserInput(DataFlow::Node node) {
  exists(Call c | c.getFunc().(Attribute).getName() = "get" and node.asExpr() = c)
}

// 传递闭包: + (一个或多个), * (零个或多个)
node.getASuccessor+()

// 量化
exists(Variable v | v.getName() = "password")
forall(Call c | c.getTarget().hasName("dangerous") | hasCheck(c))

创建查询包

codeql pack init myorg/security-queries

结构:

myorg-security-queries/
├── qlpack.yml
├── src/
│   └── SqlInjection.ql
└── test/
    └── SqlInjectionTest.expected

qlpack.yml:

name: myorg/security-queries
version: 1.0.0
dependencies:
  codeql/python-all: "*"

CI/CD集成(GitHub Actions)

name: CodeQL分析

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  schedule:
    - cron: '0 0 * * 1'  # 每周

jobs:
  analyze:
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      matrix:
        language: ['python', 'javascript']

    steps:
      - uses: actions/checkout@v4

      - name: 初始化CodeQL
        uses: github/codeql-action/init@v3
        with:
          languages: ${{ matrix.language }}
          queries: security-extended,security-and-quality
          # 添加自定义查询/包:
          # queries: security-extended,./codeql/custom-queries
          # packs: trailofbits/python-queries

      - uses: github/codeql-action/autobuild@v3

      - uses: github/codeql-action/analyze@v3
        with:
          category: "/language:${{ matrix.language }}"

测试查询

codeql test run test/

测试文件格式:

def vulnerable():
    user_input = request.args.get("q")  # 源点
    cursor.execute("SELECT * FROM users WHERE id = " + user_input)  # 警报: sql-injection

def safe():
    user_input = request.args.get("q")
    cursor.execute("SELECT * FROM users WHERE id = ?", (user_input,))  # 安全

故障排除

问题 解决方案
数据库创建失败 清理构建环境,验证构建命令独立运行
分析缓慢 使用--threads,缩小查询范围,检查查询复杂度
缺少结果 检查文件排除,验证源文件已解析
内存不足 设置CODEQL_RAM=48000环境变量(48GB)
CMake源路径问题 调整--source-root指向实际源位置

拒绝的理由

捷径 为什么错误
“没有发现意味着代码安全” CodeQL只查找它有查询的模式;新颖漏洞不会被检测到
“此代码路径看起来安全” 复杂数据流可能隐藏跨5+函数调用的漏洞;追踪完整路径
“小更改,低风险” 小更改可能引入关键错误;每次更改运行完整分析
“测试通过所以安全” 测试证明行为,而非漏洞缺失;它们测试预期路径,而非攻击者路径
“查询未标记它” 默认查询套件不覆盖所有内容;检查是否需要自定义查询

资源