CodeQL とは?
CodeQL は、開発者がセキュリティ チェックを自動化し、セキュリティ研究者がバリアント分析を実行するために使用する分析エンジンです。
CodeQL では、コードがデータのように扱われます。 セキュリティの脆弱性、バグ、その他のエラーは、コードから抽出されたデータベースに対して実行できるクエリとしてモデル化されています。 GitHub の研究者やコミュニティの共同作成者によって作成された標準の CodeQL クエリを実行することも、カスタム分析で使用するために独自に作成することもできます。 潜在的なバグを見つけるクエリを行うと、結果が直接ソース ファイルに強調表示されます。
このユニットでは、CodeQL 静的分析ツールについて、およびデータベース、クエリ スイート、クエリ言語パックを使用してバリアント分析を行う方法について学習します。
バリアント分析
バリアント分析とは、既知のセキュリティ脆弱性をシードとして使用して、コード内で同様の問題を見つけるプロセスのことです。 これは、セキュリティ エンジニアが潜在的な脆弱性を特定し、これらの脅威が複数のコードベースにわたって適切に修正されていることを確認するために使用する手法です。
CodeQL を使用したコードのクエリは、バリアント分析を実行する最も効率的な方法です。 標準の CodeQL クエリを使用してシードの脆弱性を特定することも、独自のカスタム CodeQL クエリを記述して新たな脆弱性を見つけることもできます。 そのうえで、クエリを開発または反復処理して、従来の手動による手法では見逃される可能性がある同じバグの論理バリアントを自動的に検出できます。
CodeQL データベース
CodeQL データベースには、特定時点で 1 つの言語についてコードベースから抽出されたクエリ可能なデータが含まれています。 このデータベースには、抽象構文ツリーの表現、データ フロー グラフ、制御フロー グラフなど、コード全体の階層表現が含まれます。
各言語には、データベースの作成に使用される関係を定義する、それぞれ独自のデータベース スキーマがあります。 このスキーマは、抽出プロセス中に行われる初期字句解析と、CodeQL クエリ エバリュエーターの実際の複雑な分析との間のインターフェイスになります。 スキーマでは、たとえば、すべての言語コンストラクト用のテーブルが存在することが指定されます。
言語ごとに CodeQL ライブラリによってクラスが定義され、データベース テーブルに抽象化レイヤーが形成されます。 これによってデータのオブジェクト指向ビューが得られ、クエリを簡単に記述できるようになります。
たとえば、Java プログラムの CodeQL データベースには、2 つのキー テーブルがあります。
expressions
テーブル。ビルド プロセス中に分析されたソース コード内の各式の行が含まれています。statements
テーブル。ビルド プロセス中に分析されたソース コード内の各ステートメントの行が含まれています。
CodeQL ライブラリでは、これらの各テーブル (および関連する補助テーブル) に抽象化レイヤーを形成するクラス (Expr
と Stmt
) を定義します。
クエリ スイート
CodeQL クエリ スイートを使用すると、ファイル名、ディスク上か QL パック内における場所、またはメタデータ プロパティに基づいてクエリを選択できます。 クエリ スイートは、CodeQL 分析で頻繁に使用するクエリに対して作成します。
クエリ スイートを使用すると、各クエリ ファイルへのパスを個別に指定せずに、複数のクエリを CodeQL に渡すことができます。 クエリ スイートの定義は、拡張子が .qls
の YAML ファイルに格納されます。 スイートの定義は一連の命令であり、各命令は、(通常は) 1 つのキーを持つ YAML マッピングです。 これらの命令は、クエリ スイートの定義に指定された順序で実行されます。 スイートの定義の命令がすべて実行されると、結果は、選択されたクエリのセットになります。
既定のクエリ スイート
CodeQL には、次の 2 つの組み込みクエリ スイートがあります。
default
:これらは、GitHub 上の CodeQL コード スキャンで既定で実行されるクエリであり、コード スキャンの既定の構成で使用できます。 このクエリ スイートのクエリは精度が高く、誤検知のコード スキャン結果はほとんど返されません。security-extended
クエリ スイートと比較して、default スイートでは、信頼性の低いコード スキャン結果が返されることは少なくなります。security-extended
:このスイートには、default
スイートのすべてのクエリに加えて、精度と重大度がわずかに低い追加のセキュリティ クエリが含まれています。 これは、コード スキャンの既定の構成で使用でき、クエリ スイートのドロップダウンに "拡張" オプションとして一覧表示されます。default
クエリ スイートと比較して、このスイートはより多くの誤検出コード スキャン結果を返す可能性があります。
コード スキャンの既定の構成では、default
クエリ スイートが使用されます。 これを変更するには、オーバーフロー アイコンを選択して CodeQL 構成を表示し、編集ボタンを選択します。 [スキャン設定] で、上記の 2 つのオプションのいずれかをクエリ スイートとして選択できます。
CodeQL パック
CodeQL パックは、CodeQL 分析で使用されるファイルを整理するために使用され、CodeQL クエリとライブラリを簡単に作成、共有、依存、実行できるようにします。 ここには、クエリ、ライブラリ ファイル、クエリ スイート、重要なメタデータが含まれます。 CodeQL パックと CodeQL CLI のパッケージ管理コマンドを使用すると、カスタム クエリを発行してコードベース分析に統合できます。
CodeQL パックには、クエリ パック、ライブラリ パック、モデル パックの 3 種類があります。
- クエリ パックは、実行するように設計されています。 クエリ パックが発行されると、バンドルには、クエリ ソースに加えて、各クエリのすべての推移的な依存関係とプリコンパイル済みの表現が含まれます。 これにより、パック内のクエリの一貫した効率的な実行が保証されます。
- ライブラリ パックは、クエリ パック (またはその他のライブラリ パック) で使用するように設計されており、クエリ自体は含まれません。 ライブラリは個別にコンパイルされません。
- モデル パックを使用すると、コード スキャン分析を拡張して、既定ではサポートされていない依存関係を含めることができます。 モデル パックは現在ベータ版で、変更される可能性があります。 ベータ期間中、モデル パックはリポジトリ レベルで Java 分析に使用できます。 独自のモデル パックの作成の詳細については、「CodeQL モデル パックの作成」を参照してください。
CodeQL パックの構造
CodeQL CLI を使用すると、pack init
コマンドを使用してパックの開発と発行を行うことができます。 このコマンドは、必要なディレクトリ構造とファイルを作成します。そのルート ディレクトリには、qlpack.yml
というメイン ファイルが含まれます。 各 qlpack.yml
ファイル内のメタデータは、パック内のクエリをコンパイルする方法、パックが依存するライブラリ、クエリ スイート定義を見つける場所を CodeQL に指示します。
CodeQL パックのコンテンツ (CodeQL 分析で使用されるクエリまたはライブラリ) は、qlpack.yml
と同じディレクトリ、またはそのサブディレクトリに含まれています。
qlpack.yml ファイルを含むディレクトリは、CodeQL パックのコンテンツのルート ディレクトリとして機能します。 つまり、パック内のすべての .ql
および .qll
ファイルについて、CodeQL は、パックのルートにある qlpack.yml ファイルを含むディレクトリを基準にしてすべての import ステートメントを解決します。
qlpack.yml
ファイルの例を次に示します。
name: codeql/java-queries
version: 0.0.6-dev
groups: java
suites: codeql-suites
extractor: java
defaultSuiteFile: codeql-suites/java-code-scanning.qls
dependencies:
codeql/java-all: "*"
codeql/suite-helpers: "*"
独自の CodeQL パックの作成と発行の詳細については、「CodeQL パックの発行と使用」を参照してください。[1]