CodeQL CLI を使用する

完了

GitHub.com のグラフィカル ユーザー インターフェイスに加え、コマンド ライン インターフェイスを使用して、同じ主要な CodeQL 機能の多くにアクセスすることもできます。

このユニットでは、CodeQL CLI を使用したデータベースの作成と分析、および結果の GitHub へのアップロードについて説明します。

CodeQL CLI コマンド

CI システム内のサーバーで CodeQL CLI を使用できるようにし、GitHub で確実に認証できるようにしたら、データを生成する準備が整います。

次の 3 つの異なるコマンドを使用して結果を生成し、GitHub にアップロードできます。

  • database create: リポジトリでサポートされている各プログラミング言語の階層構造を表す CodeQL データベースを作成します。
  • database analyze: クエリを実行して各 CodeQL データベースを分析し、結果を SARIF ファイルにまとめます。
  • github upload-results: 結果の SARIF ファイルを GitHub にアップロードします。そこで結果がブランチまたは pull request と照合され、コード スキャン アラートとして表示されます。

--help option を使用することで、任意のコマンドのコマンドライン ヘルプを表示できます。

GitHub でコード スキャン結果として表示する SARIF データのアップロードは、GitHub Advanced Security が有効になっている組織所有のリポジトリと、GitHub.com 上のパブリック リポジトリでサポートされています。

分析する CodeQL データベースを作成する

以下の手順に従って、分析する CodeQL データベースを作成します。

  1. 分析するコードをチェックアウトします。
    • ブランチの場合は、分析するブランチのヘッドをチェックアウトします。
    • pull request の場合は、pull request のヘッド コミットをチェックアウトするか、GitHub によって生成された pull request のマージ コミットをチェックアウトします。
  2. コードベースの環境を設定し、依存関係が使用可能であることを確認します。
  3. コードベースのビルド コマンドを見つけます (ある場合)。 通常、これは CI システムの構成ファイルで使用できます。
  4. リポジトリのチェックアウト ルートから codeql database create を実行し、コードベースをビルドします。
    • サポートされている 1 つの言語に対して 1 つの CodeQL データベースを作成するには、次のコマンドを使用します。

      codeql database create <database> --command <build> --language=<language-identifier>
      
    • サポートされている複数の言語に対して、言語ごとに 1 つの CodeQL データベースを作成するには、次のコマンドを使用します。

      codeql database create <database> --command <build> \
        --db-cluster --language=<language-identifier>,<language-identifier>
      

注意

コンテナー化されたビルドを使用する場合は、ビルド タスクが実行されるコンテナー内で CodeQL CLI を実行する必要があります。

database create コマンドのパラメーターの完全なリストを以下の表に示します。

オプション 必要な使用法
<database> CodeQL データベース用に作成するディレクトリの名前と場所を指定します。 既存のディレクトリを上書きしようとすると、コマンドは失敗します。 また --db-cluster を指定した場合は、これが親ディレクトリであり、分析される言語ごとにサブディレクトリが作成されます。
--language データベースを作成する言語の識別子 (cppcsharpgojavajavascriptpython、および ruby のいずれか) を指定します (TypeScript コードを分析するには Javascript を使用します)。 --db-cluster と一緒に使用する場合は、オプションでコンマ区切りリストが受け入れられるか、複数指定できます。
--command 推奨。 コードベースのビルド プロセスを呼び出すビルド コマンドまたはスクリプトを指定するために使用します。 コマンドは、現在のフォルダーまたは、定義されている場合は、--source-root から実行されます。 Python および JavaScript または TypeScript の分析には不要です。
--db-cluster 任意。 --language によって指定された言語ごとに 1 つのデータベースを生成するには、複数言語コードベースを使用します。
--no-run-unnecessary-builds 推奨。 CodeQL CLI でビルドを監視する必要がない言語 (Python および JavaScript または TypeScript など) のビルド コマンドを抑制するために使用します。
--source-root 省略可能。 リポジトリのチェックアウト ルートの外部で CLI を実行する場合に使用します。 既定では、database create コマンドで現在のディレクトリがソース ファイルのルート ディレクトリであると見なされます。別の場所を指定するためにこのオプションを使用します。

単一言語の例

この例では、/checkouts/example-repo でチェックアウトされたリポジトリの CodeQL データベースを作成します。 JavaScript 抽出機能を使用して、リポジトリに JavaScript および TypeScript コードの階層表現を作成します。 結果のデータベースは /codeql-dbs/example-repo に格納されます。

$ codeql database create /codeql-dbs/example-repo --language=javascript \
    --source-root /checkouts/example-repo

> Initializing database at /codeql-dbs/example-repo.
> Running command [/codeql-home/codeql/javascript/tools/autobuild.cmd]
    in /checkouts/example-repo.
> [build-stdout] Single-threaded extraction.
> [build-stdout] Extracting
...
> Finalizing database at /codeql-dbs/example-repo.
> Successfully created database at /codeql-dbs/example-repo.

複数言語の例

この例では、/checkouts/example-repo-multi でチェックアウトされたリポジトリ用に 2 つの CodeQL データベースを作成します。 イベント プロセッサで使用されるものは次のとおりです。

  • --db-cluster: 複数の言語の分析を要求します。
  • --language: データベースを作成する言語を指定します。
  • --command: コードベースのビルド コマンド (ここでは make) をツールに伝えます。
  • --no-run-unnecessary-builds: 必要のない言語 (Python など) のビルド コマンドをスキップするようにツールに伝えます。

結果のデータベースは、/codeql-dbs/example-repo-multipython および cpp サブディレクトリに格納されます。

$ codeql database create /codeql-dbs/example-repo-multi \
    --db-cluster --language python,cpp \
    --command make --no-run-unnecessary-builds \
    --source-root /checkouts/example-repo-multi
Initializing databases at /codeql-dbs/example-repo-multi.
Running build command: [make]
[build-stdout] Calling python3 /codeql-bundle/codeql/python/tools/get_venv_lib.py
[build-stdout] Calling python3 -S /codeql-bundle/codeql/python/tools/python_tracer.py -v -z all -c /codeql-dbs/example-repo-multi/python/working/trap_cache -p ERROR: 'pip' not installed.
[build-stdout] /usr/local/lib/python3.6/dist-packages -R /checkouts/example-repo-multi
[build-stdout] [INFO] Python version 3.6.9
[build-stdout] [INFO] Python extractor version 5.16
[build-stdout] [INFO] [2] Extracted file /checkouts/example-repo-multi/hello.py in 5ms
[build-stdout] [INFO] Processed 1 modules in 0.15s
[build-stdout] <output from calling 'make' to build the C/C++ code>
Finalizing databases at /codeql-dbs/example-repo-multi.
Successfully created databases at /codeql-dbs/example-repo-multi.
$

CodeQL データベースを分析する

CodeQL データベースを作成した後、これらの手順に従って分析します。

  1. 必要に応じて codeql pack download <packs> を実行し、分析中に実行する CodeQL パック (ベータ) をダウンロードします。
  2. データベースで codeql database analyze を実行し、使用するパックやクエリを指定します。
codeql database analyze <database> --format=<format> \
    --output=<output>  <packs,queries>

注意

単一コミットに対して複数の CodeQL データベースを分析する場合は、このコマンドによって生成される結果のセットごとに SARIF カテゴリを指定する必要があります。 結果を GitHub にアップロードすると、コード スキャンではこのカテゴリを使用して各言語の結果が個別に格納されます。 この操作を忘れた場合は、各アップロードで前の結果が上書きされます。

codeql database analyze <database> --format=<format> \
    --sarif-category=<language-specifier> --output=<output> \
    <packs,queries>

database analyze コマンドのパラメーターの完全なリストを以下の表に示します。

オプション 必要な使用法
<database> 分析する CodeQL データベースを含むディレクトリのパスを指定します。
<packs,queries> 実行する CodeQL パックまたはクエリを指定します。 コード スキャンに使用される標準クエリを実行するには、このパラメーターを省略します。 CodeQL CLI バンドルに含まれている他のクエリ スイートを検出する場合は、/<extraction-root>/codeql/qlpacks/codeql-<language>/codeql-suites を参照してください。 独自のクエリ スイートの作成については、CodeQL CLI のドキュメントの 「CodeQL クエリ スイートの作成」[5] を参照してください。
--format コマンドによって生成される結果ファイルの形式を指定します。 GitHub へのアップロードの場合、これは sarif-latest であるはずです。
--output SARIF 結果ファイルを保存する場所を指定します。
--sarif-category 単一データベースの分析の場合は省略可能です。 リポジトリ内の単一コミットに対して複数のデータベースを分析する場合に言語を定義するために必要です。 この分析の SARIF 結果ファイルに含めるカテゴリを指定します。 カテゴリは、同じツールとコミットに対する複数の分析を区別するために使用されますが、異なる言語またはコードの異なる部分で実行されます。
--sarif-add-query-help 省略可能。 分析で使用されるカスタム クエリに対して使用可能なマークダウン レンダリング クエリ ヘルプを含める場合に使用します。 関連するクエリによってアラートが生成された場合は、SARIF 出力に含まれるカスタム クエリのクエリ ヘルプがすべてコード スキャン UI に表示されます。
<packs> 省略可能。 CodeQL クエリ パックをダウンロードし、そのパックで指定されている既定のクエリまたはクエリ スイートを実行する場合に使用します。
--threads 任意。 複数のスレッドを使用してクエリを実行する場合に使用します。 既定値は 1 です。 クエリの実行を高速化するために、より多くのスレッドを指定できます。 スレッドの数を論理プロセッサの数に設定するには、0 を指定します。
--verbose 省略可能。 データベース作成プロセスから分析プロセスと診断データに関する詳細情報を取得するために使用します。

基本的な例

この例では、/codeql-dbs/example-repo で格納されている CodeQL データベースを分析し、結果を SARIF ファイル (/temp/example-repo-js.sarif) として保存します。 --sarif-category を使用して、結果を JavaScript として識別する追加の情報を SARIF ファイルに含めます。 これは、リポジトリ内の単一コミットに対して分析する CodeQL データベースが複数ある場合は不可欠です。

$ codeql database analyze /codeql-dbs/example-repo  \
    javascript-code-scanning.qls --sarif-category=javascript
    --format=sarif-latest --output=/temp/example-repo-js.sarif

> Running queries.
> Compiling query plan for /codeql-home/codeql/qlpacks/
    codeql-javascript/AngularJS/DisablingSce.ql.
...
> Shutting down query evaluator.
> Interpreting results.

結果を GitHub にアップロードする

SARIF アップロードでは、アップロードごとに最大 25,000 件の結果がサポートされますが、上位 5,000 件の結果のみが表示され、重大度によって優先順位が付けられます。 ツールで生成される結果が多すぎる場合は、最も重要なルールまたはクエリの結果に焦点を当てるように構成を更新する必要があります。

アップロードごとに、SARIF アップロードでサポートされる gzip 圧縮の SARIF ファイルの最大サイズは 10 MB となります。 この制限を超えるアップロードはすべて拒否されます。 含まれる結果が多すぎるために SARIF ファイルが大きくなりすぎた場合は、最も重要なルールまたはクエリの結果に焦点を当てるように構成を更新する必要があります。 制限事項の詳細と SARIF ファイルの検証については、ドキュメント [6] を参照してください。

GitHub に結果をアップロードする前に、前に作成した GitHub アプリまたは個人用アクセス トークンを CodeQL CLI に渡す最善の方法を決定する必要があります。 シークレット ストアの安全な使用に関する CI システムのガイダンスを確認することをお勧めします。 CodeQL CLI では以下がサポートされます。

  • --github-auth-stdin オプションを使用してシークレット ストアとやり取りします。 これが認証する手段として推奨されている方法です。
  • 環境変数 GITHUB_TOKEN にシークレットを保存し、--github-auth-stdin オプションを含めずに CLI を実行する。
  • --github-auth-stdin コマンド ライン オプションを渡し、標準入力を使用して一時トークンを指定します。 このオプションは、テスト用に使用することをお勧めします。

CI サーバーの最も安全で信頼性の高い方法を決定した場合は、各 SARIF 結果ファイルで codeql github upload-results を実行し、トークンが環境変数 GITHUB_TOKEN で使用可能でない限り、--github-auth-stdin を含めます。

# GitHub App or personal access token available from a secret store
<call-to-retrieve-secret> | codeql github upload-results \
    --repository=<repository-name> \
    --ref=<ref> --commit=<commit> \
    --sarif=<file> --github-auth-stdin

# GitHub App or personal access token available in GITHUB_TOKEN
codeql github upload-results \
    --repository=<repository-name> \
    --ref=<ref> --commit=<commit> \
    --sarif=<file> 

github upload-results コマンドのパラメーターの完全なリストを以下の表に示します。

オプション 必要な使用法
--repository データのアップロード先となるリポジトリの OWNER または NAME を指定します。 所有者は、GitHub Advanced Security のライセンスを持つ企業内の組織である必要があります。また、リポジトリがパブリックでない限り、GitHub Advanced Security をリポジトリに対して有効にする必要があります。
--ref チェックアウトして分析した参照の名前を指定して、結果を正しいコードと照合できるようにします。 ブランチには refs/heads/BRANCH-NAME、pull request のヘッド コミットには refs/pulls/NUMBER/head、または、pull request の GitHub により生成されたマージ コミットには refs/pulls/NUMBER/merge を使用します。
--commit 分析したコミットの完全な SHA を指定します。
--sarif 読み込む SARIF ファイルを指定します。
--github-auth-stdin 省略可能。 標準入力を介して、GitHub の REST API での認証用に作成された GitHub App または個人用アクセス トークンを CLI に渡すために使用します。 このトークンを使用して設定された GITHUB_TOKEN 環境変数にコマンドがアクセスできる場合、これは必要ありません。