CodeQL CLI完全ガイド - コード解析を自動化する
対象読者
本記事は、以下のような技術者を対象としています。
- CI/CDパイプラインにセキュリティチェックを組み込みたい開発者
- カスタムセキュリティルールを実装したいセキュリティエンジニア
- 既存のビルドプロセスにコード解析を統合したいDevOpsエンジニア
- CodeQLを使った静的解析の自動化に興味がある方
目次
- はじめに
- CodeQL CLIの仕組み
- 対応言語
- セットアップ
- 基本ワークフロー
- 出力形式
- 高度な機能
- パッケージ管理
- CI/CD統合
- パフォーマンス最適化
- トラブルシューティング
- CodeQLワークスペース
- エクストラクタオプション
- データベースの管理
- 設定ファイルの活用
- 実践的な使用例
- ベストプラクティス
- コマンドリファレンス
- 終了コード
- まとめ
1. はじめに
CodeQL CLIは、GitHubが提供するコード解析ツールです。ソースコードをデータベース化し、クエリを実行することで、セキュリティ脆弱性やコーディングエラーを発見できます。本記事では、CodeQL CLIの全体像から実践的な使い方まで、技術者として押さえておくべき内容を網羅的に解説します。
2. CodeQL CLIの仕組み
CodeQL CLIは、コードベースを解析可能なデータベース形式に変換し、そのデータベースに対してクエリを実行することで、問題を検出します。このアプローチにより、従来の構文解析ベースのツールでは発見できない、データフローやコントロールフローに関わる複雑な脆弱性も検出可能になります。
3. 対応言語
CodeQL CLIは以下の言語に対応しています。各言語に対して、専用のエクストラクタが用意されています。
| 言語 | 識別子 | 代替識別子 |
|---|---|---|
| C/C++ | c-cpp |
c または cpp
|
| C# | csharp |
- |
| Go | go |
- |
| Java/Kotlin | java-kotlin |
java または kotlin
|
| JavaScript/TypeScript | javascript-typescript |
javascript または typescript
|
| Python | python |
- |
| Ruby | ruby |
- |
| Rust | rust |
- |
| Swift | swift |
- |
| GitHub Actions | actions |
- |
4. セットアップ
4.1. CodeQL CLIのダウンロード
CodeQL CLIバンドルをダウンロードします。バンドルには以下が含まれています。
- CodeQL CLI本体
- 標準クエリパック(
codeql/cpp-queries、codeql/java-queriesなど) - プリコンパイル済みクエリ
ダウンロード元: https://github.com/github/codeql-action/releases
# Linux/macOS用のバンドルをダウンロード(例)
wget https://github.com/github/codeql-action/releases/download/codeql-bundle-vX.X.X/codeql-bundle-linux64.tar.gz
4.2. 展開と設定
# アーカイブを展開
tar -xzf codeql-bundle-linux64.tar.gz
# PATHに追加(~/.bashrcや~/.zshrcに追記推奨)
export PATH="/path/to/codeql:$PATH"
# 動作確認
codeql --version
# 出力例: CodeQL command-line toolchain release 2.15.0
4.3. セットアップの検証
# 利用可能な言語エクストラクタを確認
codeql resolve languages
# 利用可能なクエリパックを確認
codeql resolve packs
期待される出力(抜粋):
Searching the root of the CodeQL distribution.
The following packs were found:
codeql/java-all@X.X.X: (library) /path/to/codeql/qlpacks/codeql/java-all/X.X.X/qlpack.yml
codeql/java-queries@X.X.X: (query) /path/to/codeql/qlpacks/codeql/java-queries/X.X.X/qlpack.yml
...
5. 基本ワークフロー
CodeQL解析の基本的なワークフローは、以下の3ステップで構成されます。
5.1. ステップ1: データベースの作成
5.1.1. 非コンパイル言語の場合
JavaScript/TypeScript、Python、Rubyなどの非コンパイル言語では、ビルドコマンドが不要です。
# Pythonプロジェクトの例
# ソースコードのディレクトリを指定するだけでOK
codeql database create /path/to/database \
--language=python \
--source-root /path/to/source
# 実行時間の目安: 小規模プロジェクト(〜10万行)で1〜5分程度
5.1.2. コンパイル言語の場合
C/C++、Java、C#などのコンパイル言語では、ビルドプロセスをトレースする必要があります。これは、CodeQLがコンパイラの実行を監視し、どのファイルがビルドされたかを把握するためです。
Javaプロジェクト(Gradle)の例:
codeql database create java-database \
--language=java-kotlin \
--command='gradle --no-daemon clean test'
# --no-daemon: Gradleデーモンを使わない(CodeQLのトレーシングに必要)
# clean: 既存のビルド成果物を削除
# 実行時間の目安: 通常のビルド時間 + 10〜30%程度
C++プロジェクト(Make)の例:
codeql database create cpp-database \
--language=c-cpp \
--command='make -j1'
# -j1: 並列ビルドを無効化(トレーシングの正確性のため)
C#プロジェクト(.NET)の例:
codeql database create csharp-database \
--language=csharp \
--command='dotnet build /t:rebuild'
# /t:rebuild: 完全リビルドを実行(増分ビルドではなく)
5.1.3. ビルドモード
CodeQL 2.16.4以降では、--build-modeオプションでビルド方法を明示的に指定できます。
-
none: ビルドなしでデータベースを作成(C#、Java、JavaScript/TypeScript、Python、Rubyで利用可能) -
autobuild: ビルドシステムを自動検出して実行 -
manual: 手動でビルドコマンドを指定(--commandと併用)
# ビルドモード 'none' の使用例
# Javaのソースコードのみを解析(ビルド不要)
codeql database create java-database \
--language=java-kotlin \
--build-mode=none
# メリット: ビルド時間を削減できる
# デメリット: 生成されたコードは解析されない
5.1.4. 複数言語のプロジェクト
--db-clusterオプションを使用すると、複数言語のデータベースを一度に作成できます。
codeql database create /path/to/databases \
--db-cluster \
--language=python,c-cpp \
--command=make \
--no-run-unnecessary-builds
# --db-cluster: 複数のデータベースを作成
# --no-run-unnecessary-builds: Pythonはビルド不要なのでコマンドをスキップ
このコマンドは、/path/to/databases/pythonと/path/to/databases/cppという2つのデータベースを作成します。
5.2. ステップ2: クエリの実行
データベースが作成できたら、クエリを実行して脆弱性を検出します。
5.2.1. 標準クエリパックの使用
codeql database analyze java-database \
codeql/java-queries:codeql-suites/java-code-scanning.qls \
--format=sarif-latest \
--output=results.sarif \
--sarif-category=java
# codeql/java-queries: クエリパック名
# codeql-suites/java-code-scanning.qls: クエリスイート(複数のクエリをグループ化)
# --sarif-category: 複数言語を解析する場合に必須(結果を区別するため)
# 実行時間の目安: データベースサイズに依存(小規模で5〜15分程度)
5.2.2. 複数のクエリパックを実行
codeql database analyze python-database \
codeql/python-queries \
my-org/custom-python-queries \
--format=sarif-latest \
--output=results.sarif
# 標準クエリとカスタムクエリを同時に実行可能
5.2.3. クエリパックのダウンロードと実行
外部のクエリパックを使用する場合、--downloadオプションで自動ダウンロードできます。
codeql database analyze java-database \
microsoft/coding-standards@1.0.0 \
--format=sarif-latest \
--output=results.sarif \
--download
# --download: パックがローカルにない場合、自動的にダウンロード
5.2.4. 特定のクエリを実行
クエリパック内の特定のディレクトリやクエリのみを実行することもできます。
# 特定ディレクトリ内のクエリを実行
codeql database analyze python-database \
codeql/python-queries:Functions \
--format=sarif-latest \
--output=results.sarif
# 特定のクエリファイルを実行
codeql database analyze cpp-database \
'codeql/cpp-queries:experimental/Likely Bugs/RedundantNullCheckParam.ql' \
--format=sarif-latest \
--output=results.sarif
# パスにスペースやコロンが含まれる場合はクォートで囲む
5.3. ステップ3: 結果のアップロード
解析結果をGitHubにアップロードして、Code Scanningで可視化できます。
5.3.1. 基本的なアップロード
# トークンを環境変数で設定する場合
export GITHUB_TOKEN=ghp_xxxxxxxxxxxx
codeql github upload-results \
--repository=my-org/my-repo \
--ref=refs/heads/main \
--commit=abc123def456 \
--sarif=results.sarif
5.3.2. セキュアな認証方法(推奨)
# 標準入力からトークンを渡す(コマンド履歴に残らない)
echo $GITHUB_TOKEN | codeql github upload-results \
--repository=my-org/my-repo \
--ref=refs/heads/main \
--commit=abc123def456 \
--sarif=results.sarif \
--github-auth-stdin
5.3.3. 必要な権限
-
Personal Access Token:
security_eventsスコープが必要 - GitHub App: Code Scanning Alertsの読み取り/書き込み権限が必要
重要: トークンは環境変数またはシークレット管理システムで管理し、コードやログに直接記述しないでください。
6. 出力形式
CodeQL CLIは複数の出力形式に対応しています。
6.1. SARIF(推奨)
SARIF(Static Analysis Results Interchange Format)は、静的解析ツールの標準出力形式です。
--format=sarif-latest # 最新のSARIFバージョンを使用
# または
--format=sarifv2.1.0 # 特定のバージョンを指定
SARIF形式の利点:
- GitHub Code Scanningとの完全な互換性
- 豊富なメタデータ(問題の位置、重要度、説明、修正案など)
- ツール間の相互運用性(他の静的解析ツールとの統合が容易)
6.2. CSV
シンプルな表形式での出力が必要な場合に使用します。
--format=csv --output=results.csv
CSVファイルには以下の情報が含まれます。
| カラム | 内容 | 例 |
|---|---|---|
| Name | クエリ名 | Inefficient regular expression |
| Description | 説明 | A regular expression that requires... |
| Severity | 重要度 | error |
| Message | アラートメッセージ | This part of the regular expression... |
| Path | ファイルパス | /vendor/codemirror/markdown.js |
| Start line | 開始行 | 617 |
| Start column | 開始列 | 32 |
7. 高度な機能
7.1. カスタムクエリの作成
独自のセキュリティルールを定義したい場合、カスタムクエリを作成できます。
7.1.1. クエリパックの初期化
# 新しいクエリパックを作成
codeql pack init my-org/my-security-queries
# これにより以下のディレクトリ構造が作成される:
# my-security-queries/
# qlpack.yml
生成されるqlpack.yml:
name: my-org/my-security-queries
version: 0.0.1
dependencies:
# 解析対象の言語に応じて依存関係を追加
7.1.2. 依存関係の設定
name: my-org/my-security-queries
version: 1.0.0
dependencies:
codeql/java-all: ^0.1.2 # Java解析用のライブラリ
7.1.3. クエリの作成
queries/SqlInjection.ql:
/**
* @name SQLインジェクションの脆弱性
* @description ユーザー入力がSQLクエリに直接埋め込まれている
* @kind path-problem
* @problem.severity error
* @id java/sql-injection-custom
* @tags security
* external/cwe/cwe-089
*/
import java
import semmle.code.java.dataflow.TaintTracking
// クエリの実装
// ... (実際のロジック)
重要なメタデータ:
-
@id: クエリの一意識別子(必須) -
@kind: クエリの種類(problem、path-problem、diagnosticなど)(必須) -
@problem.severity: 重要度(error、warning、recommendation) -
@tags: タグ(フィルタリングに使用)
7.1.4. クエリのテスト
# テストディレクトリの構造
# tests/SqlInjection/
# SqlInjection.qlref # クエリへの参照
# Test.java # テスト用のサンプルコード
# Test.expected # 期待される結果
# クエリ参照ファイルの作成
echo "queries/SqlInjection.ql" > tests/SqlInjection/SqlInjection.qlref
# テストの実行
codeql test run tests/SqlInjection
# 期待される出力:
# Executing 1 test...
# All 1 tests passed.
テストが失敗した場合、.actualファイルが生成されます。これを確認して、期待通りの結果であれば.expectedにリネームします。
# 失敗したテストの結果を受け入れる
codeql test accept tests/SqlInjection
7.2. クエリスイートの作成
複数のクエリをグループ化して実行するには、クエリスイート(.qlsファイル)を作成します。
7.2.1. 基本的なクエリスイート
my-security-suite.qls:
- description: "カスタムセキュリティスイート"
- queries: queries # queriesディレクトリ内のすべてのクエリ
- include:
tags contain: security # securityタグを含むクエリのみ
precision:
- high
- very-high # 高精度のクエリのみ
7.2.2. 特定のクエリを除外
- qlpack: codeql/cpp-queries # 標準クエリパックを使用
- exclude:
id:
- cpp/cleartext-transmission # 特定のクエリを除外
- cpp/cleartext-storage-file
# 理由: 組織のポリシーで許可されているケースを除外する場合など
7.2.3. 正規表現による除外
- qlpack: codeql/cpp-queries
- exclude:
id:
- /^cpp\/cleartext-.*/ # cpp/cleartext-で始まるすべてのクエリを除外
7.2.4. 再利用可能な条件ファイル
reusable-conditions.yml:
- include:
kind:
- problem
- path-problem
tags contain: security
precision:
- high
- very-high
複数のクエリスイートで使用:
- queries: queries/cpp/custom
- apply: reusable-conditions.yml # 条件を適用
7.3. モデルパックによる拡張
モデルパックを使用すると、デフォルトでサポートされていないライブラリやフレームワークの解析範囲を拡張できます。現在、C/C++、C#、Java/Kotlin、Python、Ruby、Rustで利用可能です(パブリックプレビュー)。
7.3.1. モデルパックの構造
qlpack.yml:
name: my-repo/my-java-model-pack
version: 1.2.3
library: true # ライブラリパックとして定義
dependencies: {} # モデルパックは依存関係を持たない
extensionTargets:
codeql/java-all: ~1.2.3 # 適用先のクエリパック
dataExtensions:
- models/**/*.yml # データ拡張ファイルの場所
7.3.2. 使用方法
codeql database analyze java-database \
--model-packs my-repo/my-java-model-pack \
--format=sarif-latest \
--output=results.sarif \
codeql/java-queries
# 指定したモデルパックの定義が、codeql/java-queriesの解析に適用される
7.4. 脅威モデルの設定
特定の脅威モデルを有効化して、解析の範囲を調整できます。
codeql database analyze java-database \
--threat-model=local \
--format=sarif-latest \
--output=results.sarif \
codeql/java-queries
# 'local'脅威モデル: ファイルシステム、コマンドライン引数、
# データベース、環境変数などをデータソースとして扱う
脅威モデルの例:
-
default: デフォルトのリモートデータフローソース(常に有効) -
local: ローカルソース(ファイルシステム、環境変数など) -
environment: 環境変数からの入力
複数の脅威モデルを組み合わせ:
# localグループを有効化しつつ、environmentは除外
codeql database analyze java-database \
--threat-model=local \
--threat-model='!environment' \
--format=sarif-latest \
--output=results.sarif \
codeql/java-queries
8. パッケージ管理
8.1. 依存関係の追加
# 最新バージョンを追加
codeql pack add codeql/java-all
# 特定のバージョン範囲を指定
codeql pack add codeql/java-all@0.1.2
# 複数のパックを一度に追加
codeql pack add codeql/java-all codeql/util
このコマンドは、qlpack.ymlに依存関係を追加し、codeql-pack.lock.ymlを生成します。
注意: このコマンドはqlpack.ymlをフォーマットし、コメントを削除します。
8.2. 依存関係のインストール
codeql pack install
# これにより:
# 1. qlpack.ymlに記載された依存関係をダウンロード
# 2. codeql-pack.lock.ymlを生成/更新
# 3. パッケージキャッシュ(~/.codeql/packages)に保存
codeql-pack.lock.ymlの例:
dependencies:
codeql/cpp-all:
version: 0.1.4 # 実際にインストールされたバージョン
my-user/my-lib:
version: 0.2.4
8.3. 依存関係の更新
# 最新の互換バージョンに更新
codeql pack upgrade
# これにより:
# - 既存のロックファイルを無視
# - qlpack.ymlの制約内で最新バージョンを取得
# - codeql-pack.lock.ymlを更新
8.4. CI環境での依存関係管理
# CI環境では、ロックファイルの検証モードを使用
codeql pack ci
# これにより:
# - codeql-pack.lock.ymlに記載されたバージョンを使用
# - ロックファイルがqlpack.ymlと矛盾する場合はエラー
# - ロックファイルが存在しない場合もエラー
# 理由: CI環境では予期しないバージョン変更を防ぐため
8.5. クエリパックの公開
# ドライランで確認(実際には公開しない)
codeql pack publish --dry-run
# 実際に公開
echo $GITHUB_TOKEN | codeql pack publish --github-auth-stdin
# 複数のレジストリに認証が必要な場合
echo "https://containers.example1.com/v2/=TOKEN1,https://containers.example2.com/v2/=TOKEN2" | \
codeql pack publish --registries-auth-stdin
公開前にqlpack.ymlを確認:
name: my-org/my-queries
version: 1.0.0
description: "組織固有のセキュリティクエリパック"
license: MIT
dependencies:
codeql/java-all: ^0.1.2
defaultSuiteFile: codeql-suites/default.qls # デフォルトで実行されるクエリスイート
authors: security-team@my-org.com
8.6. クエリパックのダウンロード
# 最新バージョンをダウンロード
codeql pack download my-org/my-queries
# 特定バージョンをダウンロード
codeql pack download my-org/my-queries@1.0.0
# 複数のパックを一度にダウンロード
codeql pack download my-org/queries1 my-org/queries2
8.7. パック互換性の考慮
クエリパックには、プリコンパイルされたクエリが含まれています。これにより実行速度が向上しますが、CodeQLのバージョン間で互換性の問題が発生する可能性があります。
推奨事項:
- パックの公開には最新のCodeQL CLIを使用する
- パックは6ヶ月以内に再公開することを推奨
- GitHub Enterprise Serverで使用する場合は、サーバーのCodeQLバージョンと一致させる
9. CI/CD統合
9.1. GitHub Actions統合(基本)
name: "CodeQL分析"
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
analyze:
runs-on: ubuntu-latest
steps:
- name: チェックアウト
uses: actions/checkout@v3
- name: CodeQLデータベース作成
run: |
codeql database create java-db \
--language=java-kotlin \
--command='./gradlew clean build'
- name: クエリ実行
run: |
codeql database analyze java-db \
codeql/java-queries:codeql-suites/java-security-and-quality.qls \
--format=sarif-latest \
--output=results.sarif \
--sarif-category=java
- name: 結果アップロード
run: |
codeql github upload-results \
--repository=${{ github.repository }} \
--ref=${{ github.ref }} \
--commit=${{ github.sha }} \
--sarif=results.sarif
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
9.2. GitHub Actions統合(複数言語)
name: "マルチ言語CodeQL分析"
on:
push:
branches: [ main ]
jobs:
analyze:
runs-on: ubuntu-latest
strategy:
matrix:
language: [ 'java-kotlin', 'javascript-typescript' ]
steps:
- name: チェックアウト
uses: actions/checkout@v3
- name: データベース作成 - ${{ matrix.language }}
run: |
# 言語に応じてビルドコマンドを分岐
if [ "${{ matrix.language }}" = "java-kotlin" ]; then
BUILD_CMD="./gradlew clean build"
else
BUILD_CMD="" # JavaScriptはビルド不要
fi
codeql database create db-${{ matrix.language }} \
--language=${{ matrix.language }} \
${BUILD_CMD:+--command="$BUILD_CMD"}
- name: 解析実行 - ${{ matrix.language }}
run: |
codeql database analyze db-${{ matrix.language }} \
--format=sarif-latest \
--output=results-${{ matrix.language }}.sarif \
--sarif-category=${{ matrix.language }}
- name: 結果アップロード - ${{ matrix.language }}
run: |
codeql github upload-results \
--repository=${{ github.repository }} \
--ref=${{ github.ref }} \
--commit=${{ github.sha }} \
--sarif=results-${{ matrix.language }}.sarif
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
9.3. Azure DevOps統合
間接ビルドトレーシングを使用したAzure DevOpsパイプラインの例:
steps:
# CodeQL CLIのダウンロードと配置(省略)
# ステップ1: データベースの初期化
- task: CmdLine@1
displayName: CodeQLデータベース初期化
inputs:
script: |
codeql database init \
--language csharp \
--trace-process-name Agent.Worker.exe \
--source-root . \
--begin-tracing db
# ステップ2: 環境変数の設定(トレーシング開始)
- task: PowerShell@1
displayName: CodeQL環境変数設定
inputs:
targetType: inline
script: |
$json = Get-Content $(System.DefaultWorkingDirectory)/db/temp/tracingEnvironment/start-tracing.json | ConvertFrom-Json
$json.PSObject.Properties | ForEach-Object {
$template = "##vso[task.setvariable variable=" + $_.Name + "]" + $_.Value
echo "$template"
}
# ステップ3: ビルド実行(トレーシング環境下で)
- task: VSBuild@1
inputs:
solution: '**/*.sln'
clean: True # クリーンビルドを実行
# ステップ4: トレーシング終了
- task: PowerShell@1
displayName: CodeQL環境変数クリア
inputs:
targetType: inline
script: |
$json = Get-Content $(System.DefaultWorkingDirectory)/db/temp/tracingEnvironment/end-tracing.json | ConvertFrom-Json
$json.PSObject.Properties | ForEach-Object {
$template = "##vso[task.setvariable variable=" + $_.Name + "]" + $_.Value
echo "$template"
}
# ステップ5: データベース確定
- task: CmdLine@2
displayName: CodeQLデータベース確定
inputs:
script: 'codeql database finalize db'
# ステップ6: 解析実行
- task: CmdLine@2
displayName: CodeQL解析実行
inputs:
script: |
codeql database analyze db \
codeql/csharp-queries \
--format=sarif-latest \
--output=results.sarif
間接ビルドトレーシングが必要な理由: ビルドコマンドを直接指定できない場合(既存のビルドプロセスに組み込む場合など)に使用します。
9.4. Jenkins統合
pipeline {
agent any
environment {
CODEQL_HOME = '/opt/codeql'
GITHUB_TOKEN = credentials('github-token')
}
stages {
stage('チェックアウト') {
steps {
checkout scm
}
}
stage('データベース作成') {
steps {
sh '''
${CODEQL_HOME}/codeql database create java-db \
--language=java-kotlin \
--command='./gradlew clean build' \
--verbosity=progress+
'''
}
}
stage('解析実行') {
steps {
sh '''
${CODEQL_HOME}/codeql database analyze java-db \
codeql/java-queries \
--format=sarif-latest \
--output=results.sarif \
--sarif-category=java
'''
}
}
stage('結果アップロード') {
steps {
sh '''
echo $GITHUB_TOKEN | ${CODEQL_HOME}/codeql github upload-results \
--repository=${GIT_URL.replaceFirst(/^.*github\.com[:/]/, '').replaceFirst(/\.git$/, '')} \
--ref=refs/heads/${BRANCH_NAME} \
--commit=${GIT_COMMIT} \
--sarif=results.sarif \
--github-auth-stdin
'''
}
}
}
post {
always {
archiveArtifacts artifacts: 'results.sarif', allowEmptyArchive: true
}
}
}
10. パフォーマンス最適化
10.1. スレッド数の調整
# CPUコア数に合わせて自動調整(全コアを使用)
codeql database analyze db queries --threads=0
# 4スレッドで実行(明示的に指定)
codeql database analyze db queries --threads=4
# 2コアを残して実行(他のプロセス用にリソースを確保)
codeql database analyze db queries --threads=-2
推奨値:
- 小規模プロジェクト:
--threads=1(オーバーヘッドを避ける) - 中規模プロジェクト:
--threads=4 - 大規模プロジェクト:
--threads=0(全コア使用)
10.2. メモリ割り当ての調整
# 16GBのメモリを割り当て
codeql database analyze db queries --ram=16384
# データベース作成時もメモリを指定可能
codeql database create db --language=java-kotlin --ram=8192 --command='./gradlew build'
推奨値:
- 最小: 2048MB(これ以下は自動的に切り上げられる)
- 小規模プロジェクト: 4096MB
- 中規模プロジェクト: 8192MB
- 大規模プロジェクト: 16384MB以上
注意: 大規模データベースでは、ファイルベースのメモリマップがこの制限を超える可能性があります。
10.3. キャッシュの活用
# ディスクキャッシュの最大サイズを設定(10GB)
codeql database analyze db queries --max-disk-cache=10240
# ディスクの空き容量が一定以下になった場合のキャッシュ削減
codeql database analyze db queries --min-disk-free=5120
# パーセンテージで指定
codeql database analyze db queries --min-disk-free-pct=10
キャッシュの仕組み:
- 中間クエリ結果をディスクに保存
- 同じクエリを再実行する際に高速化
-
codeql database cleanupで手動削除可能
10.4. コンパイルキャッシュ
クエリのコンパイル結果はキャッシュされ、2回目以降の実行が高速化されます。
# カスタムコンパイルキャッシュの場所を指定
codeql database analyze db queries --compilation-cache=/path/to/cache
# デフォルトのコンパイルキャッシュを無効化(通常は不要)
codeql database analyze db queries --no-default-compilation-cache
キャッシュの場所:
- クエリパック内(デフォルト)
- CodeQLツールチェインディレクトリ
-
--compilation-cacheで指定した場所
10.5. クエリタイムアウトの設定
# 複雑なクエリに対して30分のタイムアウトを設定
codeql database analyze db queries --timeout=1800
# タイムアウトなし(0を指定)
codeql database analyze db queries --timeout=0
注意: タイムアウトは「永遠に実行され続ける」クエリを検出するためのものです。各評価レイヤーごとにタイムアウトが適用されます。
11. トラブルシューティング
11.1. データベース作成時のエラー
11.1.1. ビルドコマンドが失敗する場合
# より詳細なログを出力
codeql database create db \
--language=java-kotlin \
--command='./gradlew build' \
--verbosity=progress++
# さらに詳細なログをファイルに出力
codeql database create db \
--language=java-kotlin \
--command='./gradlew build' \
--verbosity=progress+++ \
--logdir=/tmp/codeql-logs
# ログファイルは /tmp/codeql-logs/ に生成される
よくあるエラーと対処法:
| エラー | 原因 | 対処法 |
|---|---|---|
No code found |
ビルドが実行されなかった | ビルドコマンドを確認、--verbosityでログを確認 |
Extractor failed |
エクストラクタの内部エラー |
--logdirでログを確認、エクストラクタオプションを調整 |
Timeout |
ビルドが長時間かかる |
--ramを増やす、並列ビルドを調整 |
11.1.2. 並列ビルドの問題
並列ビルドはトレーシングと相性が悪い場合があります。
# 並列実行を無効化(Make)
codeql database create cpp-db \
--language=c-cpp \
--command='make -j1'
# 理由: 並列ビルドではファイルの依存関係が正確にトレースできない場合がある
# Gradleの場合
codeql database create java-db \
--language=java-kotlin \
--command='gradle --no-daemon --max-workers=1 clean build'
11.1.3. メモリ不足エラー
# エラー例: OutOfMemoryError
# 対処法1: RAMを増やす
codeql database create db \
--language=java-kotlin \
--ram=16384 \
--command='./gradlew build'
# 対処法2: linkage-aware importを無効化(データベースの完全性は低下)
codeql database finalize db --no-linkage-aware-import
11.2. 診断情報の出力
解析が失敗した場合、診断情報を収集してトラブルシューティングに活用できます。
# 失敗した解析の診断情報をエクスポート
codeql database export-diagnostics db \
--format=sarif-latest \
--output=diagnostics.sarif \
--sarif-category=java \
--sarif-exit-code=1 \
--sarif-exit-code-description="Database creation failed"
# GitHubにアップロード(Tool Status Pageで確認可能)
codeql github upload-results \
--repository=my-org/my-repo \
--ref=refs/heads/main \
--commit=abc123 \
--sarif=diagnostics.sarif
11.3. データベースバンドルの作成
サポートに問い合わせる際や、チーム内でのデバッグに役立ちます。
# 推奨: すべてのトラブルシューティング情報を含める
codeql database bundle \
--output=debug-bundle.zip \
--include-diagnostics \
--include-logs \
--include-results \
-- db
# 生成されるファイルサイズ: データベースサイズ + ログ + 結果
# 小規模プロジェクトで100MB〜1GB程度
警告: データベースバンドルにはソースコードのコピーが含まれます。共有する際は、受け取る側がソースコードへのアクセス権限を持っているか確認してください。
11.4. データベースの整合性チェック
# データベースの内部整合性をチェック
codeql dataset check db/db-java-kotlin
# エラーが見つかった場合:
# - エクストラクタのバグの可能性
# - データベースが破損している可能性
11.5. クエリの結果が期待と異なる場合
# ステップ1: クエリを単独で実行してデバッグ
codeql query run queries/MyQuery.ql \
--database=db \
--output=debug-results.bqrs
# ステップ2: 結果を人間が読める形式にデコード
codeql bqrs decode debug-results.bqrs \
--format=text
# ステップ3: タプルカウントを有効にしてパフォーマンスを確認
codeql database analyze db queries/MyQuery.ql \
--tuple-counting \
--evaluator-log=eval.log
# ステップ4: ログのサマリーを生成
codeql generate log-summary eval.log
12. CodeQLワークスペース
複数の相互依存するCodeQLパックを開発する場合、ワークスペースが便利です。これにより、複数のパックを1つのリポジトリで管理できます。
12.1. ワークスペースの設定
codeql-workspace.yml:
provide:
- "*/codeql-packs/**/qlpack.yml" # このパターンに一致するqlpack.ymlをすべて含める
ignore:
- "*/codeql-packs/**/experimental/**/qlpack.yml" # 実験的なパックを除外
registries:
- packages: 'codeql/*' # codeql/で始まるパックの公開先
url: https://ghcr.io/v2/
- packages: '*' # その他すべてのパックの公開先
url: https://containers.example.com/v2/
12.2. ソース依存関係
ワークスペース内のパックは、パッケージキャッシュよりも優先して解決されます。これにより、複数のパックを同時に開発・テストする際に便利です。
# クエリパックのqlpack.yml
name: my-company/my-queries
version: 1.0.0
dependencies:
my-company/my-library: "*" # ワークスペース内から解決(バージョン制約は無視される)
codeql/cpp-all: ~0.2.0 # パッケージレジストリから解決
ソース依存関係の利点:
- ローカルでの変更が即座に反映される
- 公開前に複数パックの統合テストが可能
- バージョン管理が簡素化される
12.3. ${workspace}プレースホルダー
name: my-company/my-library
library: true
version: 1.2.3
dependencies:
my-company/my-library2: ${workspace} # 現在のワークスペースのバージョン(1.2.3)
my-company/my-library3: ^${workspace} # 互換性のある範囲(^1.2.3 = >=1.2.3 <2.0.0)
my-company/my-library4: ~${workspace} # マイナーバージョンの範囲(~1.2.3 = >=1.2.3 <1.3.0)
公開時に、これらのプレースホルダーは実際のバージョン番号に置き換えられます。
12.4. ワークスペース内のパック一覧
# ワークスペース内のすべてのパックを表示
codeql pack ls
# 特定のグループのみ表示
codeql pack ls --groups java
# 特定のグループを除外
codeql pack ls --groups java,-experimental
13. エクストラクタオプション
エクストラクタの動作をカスタマイズできます。これにより、特定のファイルの除外や、エクストラクタの挙動調整が可能になります。
13.1. 利用可能なオプションの確認
codeql resolve extractor --language=java-kotlin --format=betterjson
出力例:
{
"extractor_root": "/path/to/codeql/java",
"extractor_options": {
"option1": {
"title": "Java extractor option 1",
"description": "An example string option for the Java extractor.",
"type": "string",
"pattern": "[a-z]+"
}
}
}
13.2. コマンドラインからの設定
# 単一のオプションを設定
codeql database create db \
--language=java-kotlin \
--extractor-option java.option1=value1
# 複数のオプションを設定
codeql database create db \
--language=java-kotlin \
--extractor-option java.option1=value1 \
--extractor-option java.group1.option2=102
# エクストラクタ名を省略(すべての該当エクストラクタに適用)
codeql database create db \
--language=java-kotlin \
--extractor-option option1=value1
13.3. 設定ファイルからの読み込み
extractor-options.yml:
extractor:
java-kotlin:
option1: "値1"
group1:
option2: [102]
__allow_unknown_properties: true # 未知のオプションを無視
codeql database create db \
--language=java-kotlin \
--extractor-options-file=extractor-options.yml
優先順位:
-
--extractor-options-fileで指定したファイル(複数可、順番に処理) -
--extractor-optionで指定したオプション(ファイルより優先)
14. データベースの管理
14.1. データベースのクリーンアップ
# 基本的なクリーンアップ(一時ファイルを削除)
codeql database cleanup db
# より積極的にクリーンアップ(キャッシュをすべて削除)
codeql database cleanup db --cache-cleanup=clear
# 最小限のクリーンアップ(サイズ制限のみ適用)
codeql database cleanup db --cache-cleanup=fit
クリーンアップモード:
| モード | 説明 | 用途 |
|---|---|---|
trim(デフォルト) |
明示的にキャッシュされた述語以外を削除 | 通常使用 |
clear |
すべてのキャッシュを削除 | ディスク容量が不足している場合 |
fit |
サイズ制限を超えた分のみ削除 | 最小限のクリーンアップ |
14.2. データベースのバンドル化
# 基本的なバンドル(必須コンポーネントのみ)
codeql database bundle \
--output=my-database.zip \
-- db
# すべての情報を含める
codeql database bundle \
--output=complete-database.zip \
--include-results \
--include-logs \
--include-diagnostics \
-- db
# ファイルサイズの目安:
# - 基本: 元のデータベースサイズの50〜70%程度
# - すべて含める: 元のデータベースサイズの90〜110%程度
14.3. データベースの展開
# デフォルトの名前で展開
codeql database unbundle my-database.zip
# カスタム名で展開
codeql database unbundle my-database.zip --name=custom-db-name
# 展開先を指定
codeql database unbundle my-database.zip --target=/path/to/dir
14.4. データベースのアップグレード
# 新しいCodeQLバージョンでデータベースを使用可能にする
codeql database upgrade db
# アップグレードは不可逆的な操作です
# 実行前にバックアップを推奨
アップグレードが必要なケース:
- 古いCodeQLバージョンで作成されたデータベースを新しいバージョンで使用する場合
- データベーススキーマが変更された場合
15. 設定ファイルの活用
頻繁に使用するオプションは、設定ファイルに保存できます。これにより、コマンドラインが簡潔になり、チーム全体で一貫した設定を使用できます。
15.1. 設定ファイルの場所
- Linux/macOS:
$HOME/.config/codeql/config - Windows:
%USERPROFILE%\.config\codeql\config
15.2. 設定ファイルの例
# RAM使用量を4GBに設定(すべてのコマンドに適用)
--ram 4096
# スレッド数を4に設定
--threads 4
# カスタムパックの検索パスを追加
--search-path /path/to/my-packs
# database analyzeコマンド専用の設定
database analyze --format sarif-latest
# database createコマンド専用の設定
database create --verbose
構文ルール:
- 1行に1つのオプション
- オプションと値の間はスペースで区切る(
=は使用不可) - コマンドラインで指定したオプションが設定ファイルより優先
15.3. 検索パスの設定
# 複数の検索パスを設定(コロン区切り)
# Windows: セミコロン区切り
--search-path /path/to/packs1:/path/to/packs2:/path/to/packs3
これにより、毎回コマンドラインで指定する必要がなくなります。
16. 実践的な使用例
16.1. マルチリポジトリ分析
複数のリポジトリを一括で解析する場合のスクリプト例:
#!/bin/bash
set -e # エラー時に即座に終了
REPOS=("repo1" "repo2" "repo3")
LANGUAGE="java-kotlin"
QUERY_SUITE="codeql/java-queries:codeql-suites/java-security-extended.qls"
for REPO in "${REPOS[@]}"; do
echo "=== 解析中: $REPO ==="
# リポジトリをクローン
git clone "https://github.com/my-org/$REPO.git"
cd "$REPO"
# データベース作成(エラーハンドリング付き)
if ! codeql database create "../$REPO-db" \
--language="$LANGUAGE" \
--command='./gradlew clean build' \
--verbosity=progress+; then
echo "エラー: $REPO のデータベース作成に失敗しました" >&2
cd ..
continue # 次のリポジトリへ
fi
cd ..
# 解析実行
if ! codeql database analyze "$REPO-db" \
"$QUERY_SUITE" \
--format=sarif-latest \
--output="$REPO-results.sarif" \
--sarif-category="$LANGUAGE" \
--threads=4; then
echo "エラー: $REPO の解析に失敗しました" >&2
continue
fi
# 結果アップロード
COMMIT_SHA=$(git -C "$REPO" rev-parse HEAD)
if ! echo $GITHUB_TOKEN | codeql github upload-results \
--repository="my-org/$REPO" \
--ref=refs/heads/main \
--commit="$COMMIT_SHA" \
--sarif="$REPO-results.sarif" \
--github-auth-stdin; then
echo "エラー: $REPO の結果アップロードに失敗しました" >&2
continue
fi
echo "✓ $REPO の解析が完了しました"
done
echo "=== すべての解析が完了しました ==="
16.2. カスタムクエリの開発ワークフロー
16.3. 段階的なクエリ開発
# 1. クエリパックの初期化
codeql pack init my-org/security-queries
cd security-queries
# 2. 依存関係の追加
codeql pack add codeql/java-all
# 3. クエリの実装
mkdir -p queries
cat > queries/SqlInjection.ql << 'EOF'
/**
* @name SQLインジェクション検出
* @description ユーザー入力がSQLクエリに直接使用されている
* @kind path-problem
* @problem.severity error
* @id java/sql-injection-custom
*/
import java
// ... クエリのロジック
EOF
# 4. テストの作成
mkdir -p tests/SqlInjection
echo "queries/SqlInjection.ql" > tests/SqlInjection/SqlInjection.qlref
# テスト用のJavaコードを作成
cat > tests/SqlInjection/Test.java << 'EOF'
class Test {
void vulnerable(String userInput) {
String query = "SELECT * FROM users WHERE name = '" + userInput + "'";
// ... SQL実行コード
}
}
EOF
# 5. テストの実行
codeql test run tests/SqlInjection
# 初回は失敗するので、.actualファイルを確認して.expectedにリネーム
cp tests/SqlInjection/SqlInjection.actual tests/SqlInjection/SqlInjection.expected
# 再度テスト実行
codeql test run tests/SqlInjection
# 出力: All 1 tests passed.
# 6. 実データベースでの検証
codeql database create test-db \
--language=java-kotlin \
--command='mvn clean install'
codeql query run queries/SqlInjection.ql \
--database=test-db
# 実際のプロジェクトで期待通りの結果が出るか確認
# 7. 公開
codeql pack publish
17. ベストプラクティス
17.1. データベース作成のベストプラクティス
17.1.1. クリーンビルドの実行
# 理由: 既存のビルド成果物があると、CodeQLが追跡できないファイルが残る可能性
# Javaの例
./gradlew clean # 既存の成果物を削除
codeql database create db --language=java-kotlin --command='./gradlew build'
# C++の例
make clean
codeql database create db --language=c-cpp --command='make'
17.1.2. 並列ビルドの無効化
# 理由: CodeQLのトレーシングは並列ビルドと相性が悪い
# 並列ビルドでは、ファイルの依存関係が正確に追跡できない場合がある
# Makeの例
codeql database create db --language=c-cpp --command='make -j1'
# Gradleの例
codeql database create db \
--language=java-kotlin \
--command='gradle --no-daemon --max-workers=1 clean build'
17.1.3. ビルドキャッシュの無効化
# 理由: ビルドキャッシュがあると、一部のファイルが再コンパイルされない
# Gradleの例
codeql database create db \
--language=java-kotlin \
--command='gradle --no-daemon --no-build-cache clean test'
# --no-build-cache: ビルドキャッシュを無効化
# 実行時間は増えるが、すべてのコードが確実に解析される
17.1.4. ソースルートの適切な設定
# ソースコードのルートディレクトリを明示的に指定
codeql database create db \
--language=python \
--source-root=/path/to/project/src
# 理由: 結果のファイルパスがこのディレクトリからの相対パスになる
# GitHub Code Scanningで正しい位置に表示されるために重要
17.2. クエリ実行のベストプラクティス
17.2.1. 適切なクエリスイートの選択
# セキュリティ重視
codeql database analyze db \
codeql/java-queries:codeql-suites/java-security-extended.qls \
--format=sarif-latest \
--output=results.sarif
# セキュリティと品質の両方
codeql database analyze db \
codeql/java-queries:codeql-suites/java-security-and-quality.qls \
--format=sarif-latest \
--output=results.sarif
# 標準のコードスキャニング(バランス重視)
codeql database analyze db \
codeql/java-queries:codeql-suites/java-code-scanning.qls \
--format=sarif-latest \
--output=results.sarif
選択基準:
-
code-scanning.qls: 標準的なコードスキャニング用(偽陽性が少ない) -
security-extended.qls: セキュリティ重視(低精度のクエリも含む) -
security-and-quality.qls: セキュリティと品質の両方(実行時間が長い)
17.2.2. カテゴリの設定(複数言語の場合は必須)
# Java解析
codeql database analyze java-db queries \
--sarif-category=java-kotlin \
--format=sarif-latest \
--output=java-results.sarif
# JavaScript解析
codeql database analyze js-db queries \
--sarif-category=javascript-typescript \
--format=sarif-latest \
--output=js-results.sarif
# 理由: カテゴリがないと、後にアップロードした結果が前の結果を上書きする
17.2.3. ファイルカバレッジ情報の追加
codeql database analyze db queries \
--sarif-add-baseline-file-info \
--format=sarif-latest \
--output=results.sarif
# これにより、Tool Status Pageで解析カバレッジが表示される
# 何行のコードが解析されたかを確認できる
17.2.4. クエリヘルプの追加
# カスタムクエリのヘルプをSARIFに含める
codeql database analyze db queries \
--sarif-include-query-help=always \
--format=sarif-latest \
--output=results.sarif
# オプション:
# - always: すべてのクエリのヘルプを含める
# - custom_queries_only(デフォルト): カスタムクエリのみ
# - never: ヘルプを含めない
17.3. セキュリティのベストプラクティス
17.3.1. トークンの安全な管理
# 悪い例(コマンド履歴に残る)
codeql github upload-results --github-token=ghp_xxxx ...
# 良い例1: 環境変数
export GITHUB_TOKEN=ghp_xxxx
codeql github upload-results ...
# 良い例2: 標準入力(最も安全)
echo $GITHUB_TOKEN | codeql github upload-results --github-auth-stdin ...
# 良い例3: シークレット管理システムから取得
aws secretsmanager get-secret-value --secret-id codeql-token --query SecretString --output text | \
codeql github upload-results --github-auth-stdin ...
17.3.2. 最小権限の原則
Personal Access Tokenには、必要最小限の権限のみを付与:
-
security_eventsスコープのみ - 特定のリポジトリへのアクセスのみ(Fine-grained tokenの場合)
17.3.3. データベースバンドルの取り扱い
# データベースバンドルにはソースコードが含まれる
# 共有前に確認:
# 1. 受け取る側がソースコードへのアクセス権限を持っているか
# 2. 機密情報(APIキー、パスワードなど)が含まれていないか
# 機密情報を確認
unzip -l debug-bundle.zip | grep -E '(\.env|config|secret)'
17.4. パフォーマンスのベストプラクティス
17.4.1. リソース配分の最適化
# 小規模プロジェクト(〜10万行)
codeql database analyze db queries \
--threads=2 \
--ram=4096
# 中規模プロジェクト(10万〜100万行)
codeql database analyze db queries \
--threads=4 \
--ram=8192
# 大規模プロジェクト(100万行以上)
codeql database analyze db queries \
--threads=0 \
--ram=16384
# --threads=0: すべてのCPUコアを使用
17.4.2. キャッシュの活用
# 同じデータベースに対して複数のクエリを実行する場合
# 1回目
codeql database analyze db query-set-1 --keep-full-cache
# 2回目(キャッシュが活用され高速化)
codeql database analyze db query-set-2
# すべて完了後にクリーンアップ
codeql database cleanup db
18. コマンドリファレンス
18.1. データベース操作
| コマンド | 用途 | 主要オプション |
|---|---|---|
database create |
データベースの作成 |
--language, --command, --build-mode
|
database analyze |
クエリ実行と結果の解釈を一度に実行 |
--format, --output, --sarif-category
|
database init |
空のデータベース構造を作成(低レベル) |
--language, --source-root
|
database finalize |
データベースの確定(低レベル) | なし |
database cleanup |
一時ファイルの削除 | --cache-cleanup |
database bundle |
データベースをZIPアーカイブ化 |
--output, --include-*
|
database unbundle |
ZIPアーカイブからデータベースを展開 |
--name, --target
|
database upgrade |
データベースを新しいバージョンに更新 | なし |
database trace-command |
ビルドコマンドをトレース(低レベル) | --index-traceless-dbs |
18.2. クエリ操作
| コマンド | 用途 | 主要オプション |
|---|---|---|
query compile |
クエリのコンパイル |
--check-only, --threads
|
query run |
単一クエリの実行 |
--database, --output
|
query format |
クエリコードの自動フォーマット |
--in-place, --check-only
|
18.3. パッケージ管理
| コマンド | 用途 | 主要オプション |
|---|---|---|
pack init |
新しいパッケージの初期化 | --extractor |
pack add |
依存関係の追加とインストール | なし |
pack install |
依存関係のインストール | --mode |
pack ci |
CI用のクリーンインストール | なし |
pack upgrade |
依存関係を最新バージョンに更新 | なし |
pack publish |
パッケージの公開 | --dry-run |
pack download |
パッケージのダウンロード | なし |
pack ls |
ワークスペース内のパック一覧 | --groups |
18.4. テスト
| コマンド | 用途 | 主要オプション |
|---|---|---|
test run |
ユニットテストの実行 |
--threads, --keep-databases
|
test accept |
失敗したテストの結果を受け入れる | なし |
test extract |
テストデータベースの構築 | --print-database |
18.5. 結果の処理
| コマンド | 用途 | 主要オプション |
|---|---|---|
bqrs decode |
BQRS結果を人間が読める形式に変換 |
--format, --output
|
bqrs interpret |
BQRS結果を解釈(低レベル) |
--format, --output
|
github upload-results |
GitHub Code Scanningに結果をアップロード |
--repository, --ref, --commit
|
github merge-results |
複数のSARIFファイルをマージ |
--sarif, --output
|
18.6. 診断とデバッグ
| コマンド | 用途 | 主要オプション |
|---|---|---|
resolve languages |
インストール済みエクストラクタの一覧 | --format |
resolve packs |
利用可能なCodeQLパックの一覧 |
--format, --kind
|
resolve queries |
クエリ指定を展開 | --format |
resolve extractor |
特定言語のエクストラクタを検索 |
--language, --format
|
dataset check |
データベースの整合性チェック | なし |
database export-diagnostics |
診断情報のエクスポート |
--format, --output
|
19. 終了コード
CodeQL CLIは、処理の結果に応じて異なる終了コードを返します。スクリプトでエラーハンドリングを行う際に活用できます。
| コード | 意味 | 対処法 |
|---|---|---|
| 0 | 成功 | - |
| 1 | コマンドが「いいえ」と判断した | 正常な動作(一部のコマンドのみ) |
| 2 | エラーが発生 | エラーメッセージを確認 |
| 3 | CodeQLインストールディレクトリが見つからない | インストールを確認 |
| 32 | 解析するコードが見つからなかった | ソースルートとビルドコマンドを確認 |
| 33 | クエリがタイムアウト |
--timeoutを増やす、クエリを最適化 |
| 98 | 評価が明示的にキャンセルされた | - |
| 99 | メモリ不足 |
--ramを増やす |
| 100 | 致命的な内部エラー | バグレポートを提出 |
19.1. エラーハンドリングの例
#!/bin/bash
codeql database analyze db queries \
--format=sarif-latest \
--output=results.sarif
EXIT_CODE=$?
case $EXIT_CODE in
0)
echo "✓ 解析成功"
;;
32)
echo "⚠ 警告: 解析するコードが見つかりませんでした"
echo "ビルドコマンドを確認してください"
exit 0 # 警告として扱う(CI/CDを止めない)
;;
33)
echo "✗ エラー: クエリがタイムアウトしました"
echo "--timeout オプションを増やすか、クエリを最適化してください"
exit 1
;;
99)
echo "✗ エラー: メモリ不足"
echo "--ram オプションを増やしてください"
exit 1
;;
*)
echo "✗ エラー: 解析が失敗しました(終了コード: $EXIT_CODE)"
# ログファイルの場所を表示
echo "ログを確認してください: $(ls -t /tmp/codeql-logs/*.log | head -1)"
exit $EXIT_CODE
;;
esac
19.2. リトライロジックの実装
#!/bin/bash
MAX_RETRIES=3
RETRY_COUNT=0
while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
codeql database analyze db queries --format=sarif-latest --output=results.sarif
EXIT_CODE=$?
if [ $EXIT_CODE -eq 0 ]; then
echo "解析成功"
break
elif [ $EXIT_CODE -eq 33 ]; then
# タイムアウトの場合はリトライしない
echo "タイムアウトエラー: リトライしません"
exit 1
elif [ $EXIT_CODE -eq 99 ]; then
# メモリ不足の場合もリトライしない
echo "メモリ不足エラー: リトライしません"
exit 1
else
RETRY_COUNT=$((RETRY_COUNT + 1))
echo "エラー発生(試行 $RETRY_COUNT/$MAX_RETRIES)"
sleep 10 # 10秒待機
fi
done
if [ $RETRY_COUNT -eq $MAX_RETRIES ]; then
echo "最大リトライ回数に達しました"
exit 1
fi
20. まとめ
CodeQL CLIは、高度なコード解析を自動化するための強力なツールです。基本的なワークフロー(データベース作成→クエリ実行→結果アップロード)はシンプルですが、カスタムクエリの作成、パッケージ管理、CI/CD統合など、多様な用途に対応できる柔軟性を備えています。
20.1. 実務での活用ポイント
-
再現性:
codeql-pack.lock.ymlにより、依存関係のバージョンを固定し、環境間で一貫した結果を得られる - 拡張性: カスタムクエリやモデルパックで、組織固有のルールやフレームワークに対応できる
- 自動化: CI/CDパイプラインに組み込み、継続的なセキュリティチェックを実現できる
- 標準化: SARIF形式により、他のツールとの連携や結果の可視化が容易
20.2. 導入時の推奨ステップ
- 小規模プロジェクトで試験導入(1〜2週間)
- 標準クエリでの解析を開始
- 偽陽性の傾向を把握し、必要に応じてクエリスイートを調整
- CI/CDパイプラインに統合(段階的にロールアウト)
- 組織固有のカスタムクエリを開発(必要に応じて)
20.3. 期待される効果
- セキュリティ脆弱性の早期発見(開発段階での検出)
- コードレビューの効率化(自動チェック可能な項目を削減)
- セキュアコーディングの教育効果(アラートから学習)
- コンプライアンス要件への対応(解析証跡の保存)
CodeQL CLIを活用することで、セキュアなソフトウェア開発のワークフローを確立し、脆弱性の早期発見と修正を実現できます。