分析用コードの準備について
メモ
この記事では、GitHub Enterprise Server 3.14 の初期リリースに含まれている CodeQL CLI 2.17.6 バンドルで使用できる機能について説明します。
サイト管理者が CodeQL CLI のバージョンをより新しいリリースに更新している場合は、この記事の GitHub Enterprise Cloud バージョンで最新の機能に関する情報を参照してください。
CodeQL を使用してコードを分析する前に、コードに対してクエリを実行するために必要なすべてのデータが含まれた CodeQL データベースを作成する必要があります。 CodeQL CLI を使用すると、CodeQL データベースを自分で作成できます。
CodeQL の分析は、コードからリレーショナル データを抽出し、それを使用して CodeQL データベースを構築することに依存しています。 CodeQL データベースには、コードベースに関するすべての重要な情報が含まれており、CodeQL クエリを実行することでそれを分析できます。
CodeQL データベースを生成する前に、次のことを行う必要があります。
- CodeQL CLI をインストールして設定する。 詳しくは、「CodeQL CLI を設定する」をご覧ください。
- 分析するコードをチェックアウトします。
- ブランチの場合は、分析するブランチのヘッドをチェックアウトします。
- pull requestは、pull request のヘッド コミットをチェックアウトするか、GitHub で生成された pull request のマージ コミットをチェックアウトします。
- コードベースの環境を設定し、依存関係が使用可能であることを確認します。
- コンパイル型言語で最適な結果を得るには、コードベースのビ–ルド コマンドを見つけます (存在する場合)。 通常、これは CI システムの構成ファイルで使用できます。
コードベースの準備ができたら、codeql database create を実行してデータベースを作成できます。 詳細については、「非コンパイル型言語のデータベースを作成する」および「コンパイル型言語のデータベースを作成する」を参照してください。
実行中 codeql database create
プロジェクトのチェックアウト ルートから次のコマンドを実行すると、CodeQL データベースが作成されます。
codeql database create <database> --language=<language-identifier>
ユーザーは次のものを指定する必要があります。
-
`<database>`: 作成する新しいデータベースへのパス。 このコマンドを実行すると、このディレクトリが作成されます。既存のディレクトリを指定することはできません。 -
`--language`: どの言語のデータベースを作成するかを表す識別子。 `--db-cluster` と一緒に使用する場合は、オプションでコンマ区切りリストが受け入れられるか、複数指定できます。 CodeQL では、次の言語のデータベースの作成がサポートされています。Language 識別子 オプションの代替識別子 (存在する場合) 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| | | Swift |swift|メモ
代替識別子の 1 つを指定した場合、これは標準の言語識別子の使用と同じです。 たとえば、
javascriptの代わりにjavascript-typescriptを指定した場合、TypeScript コードの分析は除外されません。 代わりに、--codescanning-configCLI オプションを使って、paths-ignore構成キーで除外対象のファイルを指定する構成ファイルを読み込むことができます。 「コード スキャンのワークフロー構成オプション」を参照してください。または、それをサポートする言語の場合は、スキャン対象のファイルのみをビルドするカスタム ビルド コマンドを使います。 「コンパイル型言語のデータベースの作成」を参照してください。
コードベースにビルド プロセスを呼び出すビルド コマンドまたはスクリプトがある場合は、次のように指定することをお勧めします。
codeql database create <database> --command <build> \
--language=<language-identifier>
データベースを作成するためのオプション
ソース ファイルの場所、コードをコンパイルする必要があるかどうか、複数の言語の CodeQL データベースを作成するかどうかに応じて、追加のオプションを指定できます。
| Option | 必須 | Usage |
|---|---|---|
<database> | CodeQLデータベースを作成するディレクトリの名前と場所を指定します。 既存のディレクトリを上書きしようとすると、コマンドは失敗します。 また --db-cluster を指定した場合は、これが親ディレクトリであり、分析される言語ごとにサブディレクトリが作成されます。 | |
--language | c-cpp、 csharp、 go、 java-kotlin、 javascript-typescript、 python、 ruby および swift のいずれかに、データベースを作成する言語の識別子を指定します。 |
<code>
<span style="white-space: nowrap;">
--db-cluster
</span>
</code> と一緒に使用する場合は、このオプションは、カンマ区切りのリストを許可するか、複数回指定できます。 |
| --command | |
推奨。 コードベースのビルド プロセスを呼び出すビルド コマンドまたはスクリプトを指定するために使用します。 コマンドは、現在のフォルダーまたは、定義されている場合は、--source-root で実行できます。 Pythonおよび JavaScript/TypeScript の分析には必要ありません。 |
| --build-mode | |
推奨。
--command を指定しない場合は、 Java を使用して、ビルド (none) なしで CodeQL データベースを作成するか、ビルド コマンド (autobuild) の自動検出を試行するかどうかを指定します。 既定では、自動ビルド検出が使用されます。 ビルド モードの比較については、「CodeQL ビルド モード」を参照してください。 |
| --db-cluster | |
--language
によって指定された言語ごとに 1 つのデータベースを生成するには、複数言語コードベースを使用します。 |
| --no-run-unnecessary-builds | |
推奨。 CodeQL CLIがビルドをモニターする必要がない場合に、言語のビルドコマンドを抑制するために使います(たとえばPythonやJavaScript/TypeScript)。 |
| --source-root | | リポジトリのチェックアウト ルートの外部で CLI を実行する場合に使用します。 既定では、database create コマンドで現在のディレクトリがソース ファイルのルート ディレクトリであると見なされます。別の場所を指定するためにこのオプションを使用します。 |
| --codescanning-config | | [詳細設定]。 CodeQL データベースの作成方法と、後の手順で実行するクエリを指定する構成ファイルがある場合に使用します。 詳細については、「コード スキャンのワークフロー構成オプション」および「データベースの作成」を参照してください。 |
エクストラクターのオプションを指定して、CodeQL データベースを作成するエクストラクターの動作をカスタマイズできます。 詳しくは、「エクストラクターのオプション」をご覧ください。
データベースの作成時に使用できるすべてのオプションの詳細については、「AUTOTITLE」を参照してください。
単一言語の例
この例では、/checkouts/example-repo でチェックアウトされたリポジトリの単一 CodeQL データベースを作成します。 JavaScript 抽出機能を使用して、リポジトリに JavaScript および TypeScript コードの階層表現を作成します。 結果のデータベースは /codeql-dbs/example-repo に格納されます。
$ codeql database create /codeql-dbs/example-repo --language=javascript-typescript \
--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 でチェックアウトされたリポジトリの CodeQL データベースを 2 つ作成します。 イベント プロセッサで使用されるものは次のとおりです。
-
`--db-cluster`: 複数の言語の分析を要求します。 -
`--language`: データベースを作成する言語を指定します。 -
`--command`: コードベースのビルド コマンド (ここでは `make`) をツールに伝えます。 -
`--no-run-unnecessary-builds`は、必要のない言語 (Python など) のビルド コマンドをスキップするようにツールに指示します。
結果のデータベースは、python の cpp および /codeql-dbs/example-repo-multi サブディレクトリに格納されます。
$ codeql database create /codeql-dbs/example-repo-multi \
--db-cluster --language python,c-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.
$
進行状況と結果
指定したオプションに問題がある場合は、エラーが報告されます。 インタプリタ型言語の場合、 Java に --build-mode none を指定すると、抽出の進行状況がコンソールに表示されます。 ソース ファイルごとに、抽出の成功または失敗がコンソールに表示されます。 コンパイル型言語がビルドされると、コンソールには、ビルド システムの出力が表示されます。
データベースが正常に作成されると、コマンドで指定したパスに新しいディレクトリが見つかります。
--db-cluster オプションを使用して複数のデータベースを作成した場合は、言語ごとにサブディレクトリが作成されます。 各 CodeQL データベース ディレクトリには、リレーショナル データ (分析に必要) やソース アーカイブ (データベースの作成時に作られたソース ファイルのコピー) などの複数のサブディレクトリが含まれており、分析結果の表示に使用されます。
非コンパイル型言語のデータベースの作成
CodeQL CLI には、コンパイルされていない言語 (具体的には JavaScript (および TypeScript)、Python、Ruby) 用のデータベースを作成するエクストラクターが含まれています。 これらのエクストラクターは、javaScript、Python、または Ruby を --language オプションとして指定すると、database create の実行時に自動的に呼び出されます。 これらの言語のデータベースを作成するときは、追加の依存関係がすべて使用可能であることを確認する必要があります。
メモ
JavaScript、TypeScript、Python、Ruby database create を実行する場合は、--command オプションを指定しないでください。 そうでないと、通常のエクストラクター呼び出しがオーバーライドされ、空のデータベースが作成されます。 複数の言語のデータベースを作成し、そのうちの 1 つがコンパイル型言語である場合は、--no-run-unnecessary-builds オプションを使用して、コンパイルする必要のない言語のコマンドをスキップします。
JavaScript と TypeScript
JavaScript のデータベースを作成するために、追加の依存関係は必要ありませんが、プロジェクトに TypeScript ファイルが含まれている場合は、Node.js 14 以降をインストールして、PATH としての node で使用できるようにする必要があります。 コマンド ラインで --language=javascript-typescript を指定して、JavaScript と TypeScript の両方のファイルを抽出できます。
codeql database create --language=javascript-typescript --source-root <folder-to-extract> <output-folder>/javascript-database
ここでは、--source-root パスを指定しています。これはデータベースの作成が実行される場所ですが、必ずしもコードベースのチェックアウト ルートではありません。
既定では、node_modules および bower_components ディレクトリ内のファイルは抽出されません。
Python
Python用のデータベースを作成するときは、次のことを確認する必要があります。
- データ変数.product.prodname_codeql の抽出ツールには、Python 3 がインストールされており、使用可能です。
- コードによって使用されるPythonのバージョンがインストールされている。
コマンド ラインで --language=python を指定する必要があります。 例えば次が挙げられます。
codeql database create --language=python <output-folder>/python-database
これにより、コードのチェックアウト ルートから database create サブコマンドが実行され、<output-folder>/python-database に新しいPython データベースが生成されます。
Ruby
Ruby のデータベースを作成するには、追加の依存関係は必要ありません。 コマンド ラインで --language=ruby を指定する必要があります。 例えば次が挙げられます。
codeql database create --language=ruby --source-root <folder-to-extract> <output-folder>/ruby-database
ここでは、--source-root パスを指定しています。これはデータベースの作成が実行される場所ですが、必ずしもコードベースのチェックアウト ルートではありません。
コンパイル型言語のデータベースの作成
ほとんどのコンパイル型言語の場合、CodeQL からデータベースを生成するために必要なビルド システムを呼び出す必要があるため、CLI でビルド メソッドを使用できる必要があります。 この方法では、生成されたコードを含むデータベースが作成されます。 CodeQL には、コードベースを構築するための以下の 2 つの方法があります。
-
[ビルドの自動検出 (自動ビルド)](#automatically-detecting-the-build-system) -
[ユーザー指定のビルド コマンド](/code-security/codeql-cli/getting-started-with-the-codeql-cli/preparing-your-code-for-codeql-analysis#specifying-build-commands)
さらに、 Java には、コードをビルドしなくてもデータベースを生成できるオプションがあります。 これは、多数のリポジトリに対して code scanning を有効にする場合に特に便利です。 詳細については、「CodeQL ビルド モード」を参照してください。
ビルド システムを自動検出する
CodeQL CLI には、C/C++、C#、Go、Java、Kotlin、Swift コードの自動ビルダーが含まれます。 CodeQL の自動ビルダーを使用すると、ビルド コマンドを指定せずにコンパイル型言語のプロジェクトをビルドできます。 自動ビルダーが呼び出されると、CodeQL はソースでビルド システムの証拠を調べ、データベースの抽出に必要な最適なコマンドのセットを実行しようとします。 詳しくは、「コンパイル済み言語の CodeQL コード スキャン」をご覧ください。
自動ビルダーは、codeql database create オプションを含めず --command を設定しない場合に、コンパイル型言語に対して --build-mode none を実行した際に、自動で呼び出されます。 たとえば、Swift コードベースの場合は、単に次のように実行します。
codeql database create --language=swift <output-folder>/swift-database
コードベースで標準のビルド システムを使用するのであれば、多くの場合、自動ビルダーを利用することがデータベースを作成する最も簡単な方法です。 標準以外のビルド ステップを必要とするソースについては、コマンド ラインで各ステップを明示的に定義することが必要な場合があります。
メモ
- Go データベースを構築する場合は、Go ツールチェーン (バージョン 1.11 以降) をインストールし、依存関係がある場合は、適切な依存関係マネージャー (dep など) をインストールします。
- Go の自動ビルダーはリポジトリ内で、Go で記述されたコードの自動検出を試み、依存関係のフェッチを試みる際にのみビルド スクリプトを実行します。 CodeQL で強制的に、抽出をビルド スクリプトによってコンパイルされたファイルに制限するには、環境変数
CODEQL_EXTRACTOR_GO_BUILD_TRACING=onを設定するか、--commandオプションを使用してビルド コマンドを指定します。
ビルド コマンドの指定
次の例は、コンパイル型言語について指定できるビルド コマンドの一部を示すために設計されています。
メモ
`--command` オプションで受け入れられる引数は 1 つです。複数のコマンドを使用する必要がある場合は、`--command` を複数回指定します。 サブコマンドとオプションを渡す必要がある場合は、正しく解釈されるように引数全体を引用符で囲む必要があります。
-
`make` を使用してビルドされた C/C++ プロジェクト:# Disable parallel execution via `-j1` or other techniques: https://www.gnu.org/software/make/manual/make.html#Parallel-Execution codeql database create cpp-database --language=c-cpp --command=make -
`dotnet build` を使用してビルドされた C# プロジェクト:すべてのコードが確実にビルドされるように
/t:rebuildを追加するか、事前にdotnet cleanを実行することをお勧めします (ビルドされていないコードは CodeQL データベースに含まれません)。codeql database create csharp-database --language=csharp --command='dotnet build /t:rebuild' -
`CODEQL_EXTRACTOR_GO_BUILD_TRACING=on` 環境変数を使用してビルドされた Go プロジェクト:CODEQL_EXTRACTOR_GO_BUILD_TRACING=on codeql database create go-database --language=go -
カスタム ビルド スクリプトを使用してビルドされた Go プロジェクト:
codeql database create go-database --language=go --command='./scripts/build.sh' -
Gradle を使用してビルドされたプロジェクトJava:
# Use `--no-daemon` because a build delegated to an existing daemon cannot be detected by CodeQL. # To ensure isolated builds without caching, add `--no-build-cache` on persistent machines. codeql database create java-database --language=java-kotlin --command='gradle --no-daemon clean test' -
Maven を使用してビルドされたプロジェクトJava:
codeql database create java-database --language=java-kotlin --command='mvn clean install' -
Ant を使用してビルドされたプロジェクトJava:
codeql database create java-database --language=java-kotlin --command='ant -f build.xml' -
Xcode プロジェクトまたはワークスペースからビルドされた Swift プロジェクト。 既定では、最大の Swift ターゲットがビルドされます。
プロジェクトがクリーン状態であり、使用できるビルド アーティファクトがないことを確認することをお勧めします。
xcodebuild clean -all codeql database create -l swift swift-database -
`swift build` を使用してビルドされた Swift プロジェクト:codeql database create -l swift -c "swift build" swift-database -
`xcodebuild` を使用してビルドされた Swift プロジェクト:codeql database create -l swift -c "xcodebuild build -target your-target" swift-database`archive` と `test` オプション を `xcodebuild` に渡すことができます。 ただし、標準の `xcodebuild` コマンドが推奨されます。これは最も速く、スキャンが成功するために CodeQL が必要とするものが揃っています。 -
カスタム ビルド スクリプトを使用してビルドされた Swift プロジェクト:
codeql database create -l swift -c "./scripts/build.sh" swift-database -
Bazel を使用してビルドされたプロジェクト:
# Navigate to the Bazel workspace. # Before building, remove cached objects # and stop all running Bazel server processes. bazel clean --expunge # Build using the following Bazel flags, to help CodeQL detect the build: # `--spawn_strategy=local`: build locally, instead of using a distributed build # `--nouse_action_cache`: turn off build caching, which might prevent recompilation of source code # `--noremote_accept_cached`, `--noremote_upload_local_results`: avoid using a remote cache # `--disk_cache=`: avoid using a disk cache. Note that a disk cache is no longer considered a remote cache as of Bazel 6. codeql database create new-database --language=<language> \ --command='bazel build --spawn_strategy=local --nouse_action_cache --noremote_accept_cached --noremote_upload_local_results --disk_cache= //path/to/package:target' # After building, stop all running Bazel server processes. # This ensures future build commands start in a clean Bazel server process # without CodeQL attached. bazel shutdown
メモ
Go 用の Bazel ビルドは現在サポートされていません。
-
カスタム ビルド スクリプトを使用してビルドされたプロジェクト:
codeql database create new-database --language=<language> --command='./scripts/build.sh'
このコマンドにより、プロジェクトのビルドに必要なすべてのコマンドを含むカスタム スクリプトを実行します。
間接ビルド トレースの使用
コンパイル型言語の CodeQL CLI 自動ビルダーが CI ワークフローで動作せず、codeql database trace-command でビルド コマンドの呼び出しをラップできない場合は、間接ビルド トレースを使用して CodeQL データベースを作成できます。 間接ビルド トレースを使用するには、CI システムで各ビルド アクションのカスタム環境変数を設定できる必要があります。
間接ビルド トレースを使用して CodeQL データベースを作成するには、プロジェクトのチェックアウト ルートから次のコマンドを実行します。
codeql database init ... --begin-tracing <database>
ユーザーは次のものを指定する必要があります。
-
`<database>`: 作成する新しいデータベースへのパス。 このコマンドを実行すると、このディレクトリが作成されます。既存のディレクトリを指定することはできません。 -
`--begin-tracing`: ビルド コマンドがトレースされる環境を設定するために使用できるスクリプトを作成します。 `codeql database init` コマンドの他のオプションを通常どおり指定できます。
メモ
ビルドがWindowsで実行される場合は、--trace-process-level <number> または --trace-process-name <parent process name> を設定して、分析対象のコードのすべてのビルド ステップを監視する親 CI プロセスを指定する必要があります。
`codeql database init` コマンドによりメッセージが出力されます。
Created skeleton <database>. This in-progress database is ready to be populated by an extractor. In order to initialise tracing, some environment variables need to be set in the shell your build will run in. A number of scripts to do this have been created in <database>/temp/tracingEnvironment. Please run one of these scripts before invoking your build command.
Based on your operating system, we recommend you run: ...
`codeql database init` コマンドを使用すると、CodeQL で一連のビルド ステップをトレースできるようにするための環境変数と値が含まれたファイルと共に、`<database>/temp/tracingEnvironment` が作成されます。 これらのファイルには `start-tracing.{json,sh,bat,ps1}` のように名前が付けられます。 これらのファイルの 1 つを CI システムのメカニズムと共に使用して、今後の手順のための環境変数を設定します。 次のようにすることができます。
- JSON ファイルを読み取り、処理し、CI システムによって想定されている形式で環境変数を出力します。 たとえば、Azure DevOpsは
echo "##vso[task.setvariable variable=NAME]VALUE"を想定しています。 - または、CI システムで環境を永続化する場合は、適切な
start-tracingスクリプトをソースとして、CI システムのシェル環境に CodeQL 変数を設定します。
コードをビルドします。必要に応じて、end-tracing.{json,sh,bat,ps1} スクリプトが保存されているディレクトリにある start-tracing スクリプトを使用して環境変数の設定を解除してから、codeql database finalize <database> コマンドを実行します。
間接ビルド トレースを使用して CodeQL データベースを作成したら、それを他の CodeQL データベースと同様に操作できます。 たとえば、データベースを分析し、コード スキャンを使用する場合は GitHub に結果をアップロードします。
間接ビルド トレースを使用して CodeQL データベースを作成する例
メモ
Azure DevOps パイプラインを使用する場合、CodeQL データベースを作成する最も簡単な方法は、GitHub Advanced Security for Azure DevOps を使用することです。 ドキュメントについては、Microsoft Learn の「GitHub Advanced Security for Azure DevOps を構成する」を参照してください。
次の例は、Azure DevOps パイプラインで間接ビルド トレースを使用して、 CodeQL データベースを作成する方法を示しています。
steps:
# Download the CodeQL CLI and query packs...
# Check out the repository ...
# Run any pre-build tasks, for example, restore NuGet dependencies...
# Initialize the CodeQL database.
# In this example, the CodeQL CLI has been downloaded and placed on the PATH.
- task: CmdLine@1
displayName: Initialize CodeQL database
inputs:
# Assumes the source code is checked out to the current working directory.
# Creates a database at `<current working directory>/db`.
# Running on Windows, so specifies a trace process level.
script: "codeql database init --language csharp --trace-process-name Agent.Worker.exe --source-root . --begin-tracing db"
# Read the generated environment variables and values,
# and set them so they are available for subsequent commands
# in the build pipeline. This is done in PowerShell in this example.
- task: PowerShell@1
displayName: Set CodeQL environment variables
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="
$template += $_.Name
$template += "]"
$template += $_.Value
echo "$template"
}
# Execute the pre-defined build step. Note the `msbuildArgs` variable.
- task: VSBuild@1
inputs:
solution: '**/*.sln'
msbuildArgs: /p:OutDir=$(Build.ArtifactStagingDirectory)
platform: Any CPU
configuration: Release
# Execute a clean build, in order to remove any existing build artifacts prior to the build.
clean: True
displayName: Visual Studio Build
# Read and set the generated environment variables to end build tracing. This is done in PowerShell in this example.
- task: PowerShell@1
displayName: Clear CodeQL environment variables
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="
$template += $_.Name
$template += "]"
$template += $_.Value
echo "$template"
}
- task: CmdLine@2
displayName: Finalize CodeQL database
inputs:
script: 'codeql database finalize db'
# Other tasks go here, for example:
# `codeql database analyze`
# then `codeql github upload-results` ...
次のステップ
- CodeQL CLI を使用して、コードから作成したデータベースを分析する方法については、「AUTOTITLE」を参照してください。