mcpField
C
codeql

codeql

github.com/trailofbitsセキュリティ7.9k8.4k 回インストール今日更新
リポジトリ

codeql について

複数のプログラミング言語を対象とする、セキュリティ分析用の CodeQL スキルです。データベースの構築、クエリの選択、結果の確認を行う開発者向けに、データベース品質、プロジェクト固有のデータ拡張、クエリスイートの明示的な検証を重視します。

主な機能

  1. 01CodeQL データベースの構築と評価
  2. 02プロジェクト API 向けデータ拡張の作成
  3. 03ルールセットの選択とクエリ実行
  4. 04クエリスイートとデータベース品質の検証
  5. 05分析成果物とレポートの整理

活用シーン

  1. 01コードベースのセキュリティ問題を調べる
  2. 02CodeQL データベースを再利用または新規作成する
  3. 03データ拡張でフレームワーク固有 API をモデル化する
  4. 04ビルド品質の不足や結果ゼロの分析を調査する

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/trailofbits/skills --skill codeql

インストール後、Claude Code で/codeqlを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

agents/
openai.yaml
assets/
trail-of-bits-mark.svg
references/
build-fixes.md
diagnostic-query-templates.md
extension-yaml-format.md
important-only-suite.md
language-details.md
macos-arm64e-workaround.md
performance-tuning.md
quality-assessment.md
ruleset-catalog.md
run-all-suite.md
sarif-processing.md
threat-models.md
scripts/
build_log.sh
check_db_quality.py
find_databases.sh
generate_suite.sh
pyproject.toml
test_build_log.py
test_build_mode_claims.py
test_check_db_quality.py
test_find_databases.py
test_generation_scripts.py
test_script_flags.py
test_section_pointers.py
test_shell_blocks.py
test_suite_templates.py
test_verify_query_suite.py
verify_query_suite.py

詳細

CodeQL 分析

対応言語:Python、JavaScript/TypeScript、Go、Java/Kotlin、C/C++、C#、Ruby、Swift。

スキルリソース: リファレンスファイルとテンプレートは {baseDir}/references/ および {baseDir}/workflows/ にあります。

重要な原則

  1. データベースの品質は妥協できません。 ビルドが成功したデータベースが、必ずしも良質とは限りません。キャッシュされたビルドでは、成功を報告しながら何も抽出されていない場合があります。

  2. データ拡張により、CodeQL が見逃す問題を検出できます。 Django、Spring、Express のプロジェクトでは、出荷済みのモデルでは対応していないプロジェクト固有の API に、データベース呼び出し、リクエストの解析、シェル実行がラップされている場合があります。

  3. スイートを明示的に指定すると、クエリが暗黙に除外されるのを防げます。 codeql database analyze にパック名を渡さないでください。各パックの defaultSuiteFile では、結果がゼロになる可能性のある非表示のフィルターが適用されます。必ず .qls を生成してください。

  4. 検出結果がゼロの場合は、喜ぶのではなく調査が必要です。 抽出の品質が低い、モデルが不足している、パックが誤っている、またはスイートでフィルターされている可能性があります。ビルド後に {baseDir}/scripts/check_db_quality.py を実行し、使用中のスイートに対して {baseDir}/scripts/verify_query_suite.py がゼロで終了したことを確認してください。生成スクリプトではこれを実行するため、再利用するスイートまたは手動編集したスイートに対してのみ、手動で実行してください。レポートには、両方のチェックに合格したことを記載してください。

  5. macOS の Apple Silicon でコンパイル言語を使う場合は、回避策が必要です。 終了コード 137 はビルド失敗ではなく、arm64e と arm64 の不一致を示しています。build-mode=none に切り替える前に、Homebrew の arm64 ツールまたは Rosetta を試してください。

  6. ワークフローは手順どおりに進めてください。 各フェーズが次のフェーズの実行条件になっています。品質評価やデータ拡張を省略すると、結果に現れない問題が残ります。

Bash の呼び出しごとに新しいシェルが起動します

Bash の呼び出しをまたいで引き継がれるものはありません。変数、配列、build_log.sh から読み込んだ関数も引き継がれません。以下の各ブロックで値を使用する場合は、同じブロック内で設定し直してください。ワークフローではこの説明を繰り返さず、ここを参照しています。各ケースで異なる問題が発生し、いずれも気付かれないまま失敗するため、ここではその具体的な影響を説明します。

  • 関数が失われると、run_logged は終了コード 127 で終了します。ビルド手順ではこれを失敗した方法として扱い、--build-mode=none まで順に進んでしまい、CodeQL は実行されません。
  • 配列が失われると、何も展開されません。そのため、ユーザーが選択したすべての --threat-model と --model-packs が無視される一方、最終レポートには使用したと記載されます。
  • set -u のもとで スカラーが失われると、unbound variable でブロックが中断されます。

出力ディレクトリ

生成されるすべてのファイル(データベース、ビルドログ、診断情報、拡張機能、結果)は、1 つの出力ディレクトリに保存されます。

  • ユーザーがプロンプトで出力ディレクトリを指定した場合は、それを OUTPUT_DIR として使用します。
  • 指定がない場合は、./static_analysis_codeql_1 をデフォルトとして使用します。すでに存在する場合は、_2、_3 のように番号を増やします。

どちらの場合も、ファイルを書き込む前に必ず mkdir -p でディレクトリを作成してください。

これを実行する前に、USER_SPECIFIED_DIR にユーザーのプロンプトに記載されたパスをそのまま設定してください。自動で番号を増やす場合は、設定しないでください。これ以外の箇所でこの変数に値を代入しないでください。

# Resolve output directory
USER_SPECIFIED_DIR="${USER_SPECIFIED_DIR:-}"   # substitute the user's path here, if any
if [ -n "$USER_SPECIFIED_DIR" ]; then
  OUTPUT_DIR="$USER_SPECIFIED_DIR"
else
  BASE="static_analysis_codeql"
  N=1
  while [ -e "${BASE}_${N}" ]; do
    N=$((N + 1))
  done
  OUTPUT_DIR="${BASE}_${N}"
fi
mkdir -p "$OUTPUT_DIR"

出力ディレクトリは、ワークフローを実行する前の開始時に一度だけ決定されます。すべてのワークフローには $OUTPUT_DIR が渡され、生成物はそのディレクトリに保存されます。

$OUTPUT_DIR/
├── rulesets.txt                 # Selected query packs (logged after Step 3)
├── codeql.db/                   # CodeQL database (dir containing codeql-database.yml)
├── build.log                    # Build log
├── codeql-config.yml            # Exclusion config (interpreted languages)
├── diagnostics/                 # Diagnostic queries and CSVs
├── extensions/                  # Data extension YAMLs
├── raw/                         # Unfiltered analysis output
│   ├── results.sarif
│   └── run-all.qls | important-only.qls
└── results/                     # Final results (filtered for important-only, copied for run-all)
    └── results.sarif
データベースの検出

CodeQL データベースは、そのディレクトリ内に codeql-database.yml マーカーファイルが存在することで識別できます。既存のデータベースを検索するときは、一致したものを必ずすべて収集してください。以前の実行で作成されたデータベースや、言語ごとに複数のデータベースが存在する場合があります。

検出コマンド。 find_databases.sh は、ビルドに失敗したときに残るマーカーファイルを除外し、データベースのパスを1行ずつ出力します。配列は、そこから選択するのと同じブロック内で構築してください。Bash の呼び出しごとに新しいシェルが起動するため、ここで構築した配列は次の呼び出しでは空になり、データベースが存在しないという結論になります。

# Command substitution, not `done < <(...)`: a process substitution discards the script's
# exit status, so "codeql is not on this shell's PATH" (exit 2) would arrive as an empty
# list and route to "build a new database" with three good ones sitting on disk.
if ! DB_LIST=$("{baseDir}/scripts/find_databases.sh" "${OUTPUT_DIR:-.}" .); then
  echo "ERROR: database discovery failed — see the message above" >&2
  exit 1
fi

FOUND_DBS=()
while IFS= read -r db; do
  [ -n "$db" ] || continue
  FOUND_DBS+=("$db")
done <<<"$DB_LIST"

echo "Found ${#FOUND_DBS[@]} existing database(s)"

# The metadata the selection prompt needs, collected here rather than in a block of its
# own: FOUND_DBS is gone by the next Bash call, and a loop over an array that no longer
# exists prints nothing and reports success.
for db in "${FOUND_DBS[@]}"; do
  CODEQL_LANG=$(codeql resolve database --format=json -- "$db" 2>/dev/null | jq -r '.languages[0]')
  CREATED=$(grep '^creationMetadata:' -A5 "$db/codeql-database.yml" 2>/dev/null | grep 'creationTime' | awk '{print $2}')
  echo "$db — language: $CODEQL_LANG, created: $CREATED"
done

データベース名が codeql.db だと決めつけないでください。マーカーファイルを使って検出してください。

複数のデータベースが見つかった場合: AskUserQuestion を使って、上に表示された言語と作成時刻をもとに、使用するデータベースを選択するか、新しいデータベースを構築するかをユーザーに選んでもらいます。AskUserQuestion の選択肢は最大4つです。データベースがそれより多い場合は、最も新しい3つと「新しいデータベースを構築する」を提示し、残りはプロンプト本文に列挙してください。ユーザーがプロンプトで使用するデータベース、または新しいデータベースを構築することを明示している場合は、AskUserQuestion を省略してください。

クイックスタート

よくあるケース(「このコードベースをスキャンして脆弱性を検出する」)の場合:

# Verify CodeQL is installed. Stop here if it is not — every later command fails with
# a less informative error, and the run wastes a build cycle before saying why.
if ! command -v codeql >/dev/null 2>&1; then
  echo "ERROR: codeql not found on PATH. Install it with one of:" >&2
  echo "  gh extension install github/gh-codeql   # then: gh codeql install-stub" >&2
  echo "  brew install --cask codeql" >&2
  echo "  https://github.com/github/codeql-action/releases  (codeql-bundle)" >&2
  exit 1
fi

# jq parses `codeql resolve database --format=json` in the very next step. Without it
# CODEQL_LANG comes back empty and the run continues against the wrong language.
if ! command -v jq >/dev/null 2>&1; then
  echo "ERROR: jq not found on PATH (brew install jq / apt install jq)" >&2
  exit 1
fi

# uv runs both guard scripts and both suite generators. Check it here rather than at
# suite generation, which is after the build — otherwise a machine without uv spends
# the whole build before failing.
if ! command -v uv >/dev/null 2>&1; then
  echo "ERROR: uv not found on PATH (https://docs.astral.sh/uv/getting-started/)" >&2
  exit 1
fi

codeql --version

次に、上記の出力ディレクトリのブロックを使って OUTPUT_DIR を解決してください。単純な自動採番とは異なり、ユーザーが指定したディレクトリが反映されます。

続いて、以下のワークフローを使って、パイプライン全体を実行します。データベースを構築 → データ拡張を作成 → 分析を実行。

退けるべき誤った理屈

これらの近道は検出漏れにつながります。受け入れないでください。

  • 「security-extended で十分」 — これはベースラインです。その言語で Trail of Bits パックと Community Packs が利用できるか、必ず確認してください。これらは security-extended ではまったく検出できないカテゴリを検出します。
  • 「security-and-quality が最も網羅的なスイート」 — security-and-quality はすべての experimental/ クエリパスを除外します。全件実行モードでは、security-and-quality と security-experimental の両方をインポートしてください。差分は言語によって1〜52件のクエリです。
  • 「データベースを構築できたので問題ない」 — データベースを構築できても、抽出が適切に行われたとは限りません。必ず品質評価を実行し、ファイル数を想定されるソースファイルと照合してください。
  • 「標準的なフレームワークならデータ拡張は不要」 — Django や Spring のアプリにも、CodeQL がモデル化していない独自のラッパーが存在します。拡張を省略すると、脆弱性を見逃します。
  • 「コンパイル言語でも build-mode=none で問題ない」 — 分析が著しく不完全になります。最後の手段としてのみ使用してください。macOS では、まず arm64 ツールチェーンの回避策か Rosetta を試してください。
  • 「macOS でビルドに失敗したので、build-mode=none を使えばよい」 — 終了コード137の原因は arm64e/arm64 の不一致であり、根本的なビルド失敗ではありません。macOS arm64e の回避策を参照してください。
  • 「検出結果がないので、コードは安全だ」 — check_db_quality.py と verify_query_suite.py を実行し、合格したことを報告してください。これらを実行しなければ、検出結果がゼロである場合と、データベースから何も抽出されなかった場合は、同じ結果になります。
  • 「デフォルトのスイートを実行すればよい」/「パック名を直接渡せばよい」 — 各パックの defaultSuiteFile は見えないフィルターを適用するため、結果がゼロになることがあります。必ず明示的なスイート参照を使用してください。
  • 「ファイルは現在のディレクトリに置けばよい」 — 生成したファイルはすべて $OUTPUT_DIR に置いてください。作業ディレクトリにファイルを散在させると、クリーンアップが困難になり、以前の実行結果を上書きするおそれがあります。
  • 「見つかった最初のデータベースを使えばよい」 — 言語ごと、または以前の実行によって、複数のデータベースが存在する場合があります。複数見つかった場合は、すべての選択肢をユーザーに提示してください。プロンプトを省略できるのは、ユーザーが使用するデータベースをすでに指定している場合のみです。
  • 「ユーザーが『スキャン』と言ったのだから、使うデータベースを選んでほしいということだ」 — 「スキャン」はデータベースの選択を意味しません。複数のデータベースが存在し、ユーザーがどれを使うか指定していない場合は、確認してください。

ワークフローの選択

このスキルには3つのワークフローがあります。ワークフローを選択したら、フェーズを飛ばさず、順番に実行してください。

これらの実行には時間がかかります。データベースのビルドには4つのフォールバック方法があるため、タスクツールを使って進捗を追跡してください。実行内容に応じて、追跡する価値のあるステップを判断してください。

ワークフロー目的
build-databaseビルド方法を順に試してCodeQLデータベースを作成します
create-data-extensionsプロジェクトのAPI向けデータ拡張モデルを検出または生成します
run-analysisルールセットを選択し、クエリを実行して、結果を処理します
無人でのビルド

このプラグインには /static-analysis:codeql-build が付属しており、build-databaseの手順を最初から最後まで実行します。言語とツールチェーンを検出し、方法を順に試しながら各段階の間に build-fixes.md の修正を適用し、品質ゲートを適用します。

/static-analysis:codeql-build {"target": "/abs/path", "lang": "cpp"}

何も尋ねません。すべての方法が失敗した場合や、ビルドされたデータベースが品質しきい値を下回った場合は、no-method-succeeded および built-below-threshold のステータスが返されるため、ここで対応できます。残ったエクストラクターエラーが、分析する必要のないコードに限られるかどうかは、実行側では判断できないためです。

ビルドに時間がかかり、結果が不確実な場合に、結論が出るまで任せたいなら、この方法を使ってください。どの方法を試すかを自分で決めたい場合や、ビルドの失敗を発生時に解釈する必要がある場合は、build-database.md の手順を手動で進めてください。

自動検出ロジック

ユーザーが実行内容を明示している場合(例:「データベースをビルドして」「./my-db で分析を実行して」)は、該当するワークフローを直接実行してください。ユーザーのプロンプトから意図が明確な場合は、データベースの選択について AskUserQuestion を呼び出さないでください。例:「新しいデータベースをビルドして」「static_analysis_codeql_2 の codeql データベースを分析して」「最初からフルスキャンを実行して」。

「test」「scan」「analyze」などのデフォルトパイプライン: 上記の データベースの検出 に記載されたコマンドで既存のデータベースを検出してから、次のように判断してください。

条件アクション
データベースが見つからない新しい $OUTPUT_DIR を解決し、ビルド → 拡張 → 分析(フルパイプライン)を実行します
データベースが1つ見つかったAskUserQuestion を使い、再利用するか新規作成するかを尋ねます
複数のデータベースが見つかったデータベースの検出 を参照し、選択肢を最大4つにして AskUserQuestion を使います
ユーザーが意図を明示しているAskUserQuestion を省略し、指示どおりに実行します
データベース選択の質問

既存のデータベースが見つかり、ユーザーがどれを使うか明示していない場合は、AskUserQuestion を使い、「Existing CodeQL Databases」というヘッダーの下に表示してください。各選択肢には、上記で取得したパス、言語、作成時刻を含めてください。例:./static_analysis_codeql_1/codeql.db (language: python, created: 2026-02-24)。最後の選択肢は「Build a new database」にしてください。

選択後:

  • ユーザーが既存のデータベースを選んだ場合: $OUTPUT_DIR をその親ディレクトリ(またはデータベースを含むディレクトリ)に設定し、$DB_NAME を選択されたパスに設定してから、拡張 → 分析に進みます。
  • ユーザーが「Build new」を選んだ場合: 新しい $OUTPUT_DIR を解決し、ビルド → 拡張 → 分析を実行します。
一般的な選択の質問

データベースとワークフローのどちらもプロンプトから明確でない場合は、AskUserQuestion を使い、4つのワークフロー(フルスキャン(推奨)、データベースのビルド、データ拡張の作成、分析の実行)を提示してください。見つかったデータベースと、解決した $OUTPUT_DIR も示してください。


参照インデックス

ファイル内容
スクリプト
scripts/verify_query_suite.pyクエリ数がゼロになるスイートを失敗とします。生成スクリプトから実行されます。再利用するスイート、または手動で編集したスイートに対してのみ、手動で実行してください
scripts/check_db_quality.py解析可能なソースがないデータベースを失敗とします。ビルドのたびに実行してください
scripts/build_log.shlog_step/run_logged ヘルパーです。ビルド手順を実行する前に source してください
scripts/find_databases.shcodeql resolve database が受け付けるすべてのデータベースを、1 行に 1 つずつ出力します。これを読み取るブロック内で、出力から配列を構築してください
scripts/generate_suite.shrun-all または important-only の .qls を書き込み、解決後のクエリ数がゼロでないことを検証します
参照資料 — 3 つのワークフローは ワークフローの選択 に記載されています
references/macos-arm64e-workaround.mdApple Silicon でのビルドトレースの回避策
references/build-fixes.mdビルド失敗の修正カタログ
references/quality-assessment.mdデータベースの品質指標と改善策
references/extension-yaml-format.mdデータ拡張 YAML の列定義と例
references/sarif-processing.mdSARIF 出力を処理する jq コマンド
references/diagnostic-query-templates.mdソース/シンクを列挙する QL クエリ
references/important-only-suite.mdimportant-only スイートのテンプレートと生成
references/run-all-suite.mdrun-all スイートのテンプレート
references/ruleset-catalog.md言語別に利用可能なクエリパック
references/threat-models.md脅威モデルの設定
references/language-details.md言語固有のビルドと抽出の詳細
references/performance-tuning.mdメモリ、スレッド、タイムアウトの設定

成功基準

CodeQL の分析を完全に実行するには、次の条件を満たす必要があります。

  • 出力ディレクトリが解決されている(ユーザー指定、または自動採番されたデフォルト)
  • 生成されたすべてのファイルが $OUTPUT_DIR 内に保存されている
  • データベースがビルドされ(codeql-database.yml マーカーで検出)、{baseDir}/scripts/check_db_quality.py が終了コード 0 で終了している
  • データ拡張が評価されている — $OUTPUT_DIR/extensions/ に作成されているか、正当な理由を添えて明示的にスキップされている
  • 明示的なスイート参照(デフォルトのパックのスイートではない)を指定して分析を実行し、そのスイートに対して {baseDir}/scripts/verify_query_suite.py が終了コード 0 で終了している
  • インストール済みのすべてのクエリパック(公式、Trail of Bits、Community)が使用されているか、明示的に除外されている
  • 選択したクエリパックが $OUTPUT_DIR/rulesets.txt に記録されている
  • フィルター前の結果が $OUTPUT_DIR/raw/results.sarif に保持されている
  • 最終結果が $OUTPUT_DIR/results/results.sarif に保存されている(important-only の場合はフィルター処理し、run-all の場合はコピー)
  • 検出結果がゼロの場合に調査されている(データベースの品質、モデルのカバレッジ、スイートの選択)
  • すべてのコマンド、修正、品質評価を含むビルドログが $OUTPUT_DIR/build.log に保持されている

コメント