分析用コードの準備について
メモ
この記事では、CodeQL CLI 3.20 の初期リリースに含まれている 2.23.9 GitHub Enterprise Server バンドルで使用できる機能について説明します。
サイト管理者が CodeQL CLI のバージョンをより新しいリリースに更新している場合は、この記事の GitHub Enterprise Cloud バージョンで最新の機能に関する情報を参照してください。
CodeQLを使用してコードを分析する前に、コードに対してクエリを実行するために必要なすべてのデータを含むCodeQL データベースを作成する必要があります。 CodeQLを使用して、CodeQL CLIデータベースを自分で作成できます。
CodeQL 分析は、コードからリレーショナル データを抽出し、それを使用して CodeQL データベースを構築することに依存します。 CodeQL データベースには、コードベースに関するすべての重要な情報が含まれています。コードベースに対して CodeQL クエリを実行することで分析できます。
CodeQL データベースを生成する前に、次の作業を行う必要があります。
- CodeQL CLIをインストールして設定します。 詳細については、「CodeQL CLI を設定する」を参照してください。
- 分析するコードをチェックアウトします。
- ブランチの場合は、分析するブランチのヘッドをチェックアウトします。
- プル リクエストの場合は、プル リクエストのヘッド コミット、または GitHub によって生成されたプル リクエストのマージ コミットをチェックアウトします。
- コードベースの環境を設定し、依存関係が使用可能であることを確認します。
- コンパイル型言語で最適な結果を得るには、コードベースのビ–ルド コマンドを見つけます (存在する場合)。 通常、これは CI システムの構成ファイルで使用できます。
コードベースの準備ができたら、codeql database create を実行してデータベースを作成できます。 詳細については、「非コンパイル型言語のデータベースを作成する」および「コンパイル型言語のデータベースを作成する」を参照してください。
実行中 codeql database create
CodeQL データベースは、プロジェクトのチェックアウト ルートから次のコマンドを実行して作成されます。
codeql database create <database> --language=<language-identifier>
ユーザーは次のものを指定する必要があります。
-
<database>: 作成する新しいデータベースへのパス。 このコマンドを実行すると、このディレクトリが作成されます。既存のディレクトリを指定することはできません。 -
--language: どの言語のデータベースを作成するかを表す識別子。--db-clusterと一緒に使用する場合は、オプションでコンマ区切りリストが受け入れられるか、複数指定できます。 CodeQL では、次の言語のデータベースの作成がサポートされています。Language 識別子 オプションの代替識別子 (存在する場合) C/C++ c-cppcまたはcppC# csharpGitHub Actionsのワークフロー actionsGo goJava/Kotlin java-kotlinjavaまたはkotlinJavaScript/TypeScript javascript-typescriptjavascriptまたはtypescriptPython pythonRuby rubyRust rustSwift swiftメモ
代替識別子の 1 つを指定した場合、これは標準の言語識別子の使用と同じです。 たとえば、
javascriptの代わりにjavascript-typescriptを指定した場合、TypeScript コードの分析は除外されません。 代わりに、--codescanning-configCLI オプションを使って、paths-ignore構成キーで除外対象のファイルを指定する構成ファイルを読み込むことができます。 「コード スキャンのワークフロー構成オプション」を参照してください。または、それをサポートする言語の場合は、スキャン対象のファイルのみをビルドするカスタム ビルド コマンドを使います。 「コンパイル型言語のデータベースの作成」を参照してください。
コードベースにビルド プロセスを呼び出すビルド コマンドまたはスクリプトがある場合は、次のように指定することをお勧めします。
codeql database create <database> --command <build> \
--language=<language-identifier>
データベースを作成するためのオプション
ソース ファイルの場所、コードをコンパイルする必要がある場合、および複数の言語用に CodeQL データベースを作成する場合に応じて、追加のオプションを指定できます。
| Option | Required | 使用方法 |
|---|---|---|
<database> | ||
CodeQL データベース用に作成するディレクトリの名前と場所を指定します。 既存のディレクトリを上書きしようとすると、コマンドは失敗します。 また --db-cluster を指定した場合は、これが親ディレクトリであり、分析される言語ごとにサブディレクトリが作成されます。 | ||
--language | データベースを作成する言語の識別子 ( c-cpp、 csharp、 go、 java-kotlin、 javascript-typescript、 python、 ruby、 rust および swiftのいずれか) を指定します。 |
--db-cluster
と一緒に使用する場合は、このオプションは、カンマ区切りのリストを許可するか、複数回指定できます。 |
| --command | |
**推奨。** コードベースのビルド プロセスを呼び出すビルド コマンドまたはスクリプトを指定するために使用します。 コマンドは、現在のフォルダーまたは、定義されている場合は、--source-root で実行できます。 Pythonおよび JavaScript/TypeScript の分析には必要ありません。 |
| --build-mode | |
**推奨。**
`--command` を指定しない場合は、C/C++、C#, Java および Rust を使用して、ビルドなしで CodeQL データベースを作成する (`none`) か、ビルド コマンドの自動検出を試みる (`autobuild`) かを指定します。 既定では、自動ビルド検出が使用されます。 ビルド モードの比較については、[「CodeQL ビルド モード」](/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages#codeql-build-modes)を参照してください。 |
| --db-cluster | |
--language
によって指定された言語ごとに 1 つのデータベースを生成するには、複数言語コードベースを使用します。 |
| --no-run-unnecessary-builds | |
**推奨。**
CodeQL CLIがビルドを監視する必要がない言語 (Pythonや JavaScript/TypeScript など) のビルド コマンドを抑制するために使用します。 |
| --source-root | | リポジトリのチェックアウト ルートの外部で CLI を実行する場合に使用します。 既定では、`database create` コマンドで現在のディレクトリがソース ファイルのルート ディレクトリであると見なされます。別の場所を指定するためにこのオプションを使用します。 |
| --codescanning-config | | Advanced.
CodeQL データベースの作成方法と、後の手順で実行するクエリを指定する構成ファイルがある場合に使用します。 詳細については、「[AUTOTITLE](/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning#custom-configuration-files)」および「[AUTOTITLE](/code-security/codeql-cli/codeql-cli-manual/database-create#--codescanning-configfile)」を参照してください。 |
抽出オプションを指定して、 CodeQL データベースを作成するエクストラクターの動作をカスタマイズできます。 詳細については、「エクストラクターのオプション」を参照してください。
データベースの作成時に使用できるすべてのオプションの詳細については、「AUTOTITLE」を参照してください。
単一言語の例
この例では、CodeQLでチェックアウトされたリポジトリ用の単一の/checkouts/example-repo データベースを作成します。 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.
複数言語の例
この例では、CodeQLでチェックアウトされたリポジトリ用の 2 つの/checkouts/example-repo-multi データベースを作成します。 以下を使用します。
--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.
$
進行状況と結果
指定したオプションに問題がある場合は、エラーが報告されます。 解釈された言語の場合、および--build-mode noneにC/C++、C#, Java および Rustを指定すると、抽出の進行状況がコンソールに表示されます。 ソース ファイルごとに、抽出の成功または失敗がコンソールに表示されます。 コンパイル型言語がビルドされると、コンソールには、ビルド システムの出力が表示されます。
データベースが正常に作成されると、コマンドで指定したパスに新しいディレクトリが見つかります。
--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用のデータベースを作成するときは、次のことを確認する必要があります。
- Python 3 がインストールされており、CodeQL エクストラクターで使用できます。
- コードによって使用される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 つのメソッドがあります。
さらに、 C/C++、C#, Java および Rustでは、コードをビルドせずにデータベースを生成するオプションがあります。 これは、多数のリポジトリに対して code scanning を有効にする場合に特に便利です。 詳細については、「CodeQL ビルド モード」を参照してください。
ビルド システムを自動検出する
CodeQL CLIには、C/C++、C#、Go、Java、Kotlin、Swift コード用のオートビルダーが含まれています。 CodeQL autobuilder を使用すると、ビルド コマンドを指定せずにコンパイル済み言語のプロジェクトをビルドできます。 自動ビルダーが呼び出されると、 CodeQL はソースでビルド システムの証拠を調べ、データベースの抽出に必要な最適なコマンド セットの実行を試みます。 詳細については、「CodeQL code scanning for compiled languages」を参照してください。
自動ビルダーは、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' -
Cargo を使用して構築された Rust プロジェクト:
codeql database create rust-database --language=rust -
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 コマンドは、環境変数と値を含むファイルを含む<database>/temp/tracingEnvironmentを作成し、CodeQLが一連のビルド ステップをトレースできるようにします。 これらのファイルには 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 の Configure 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を使用してコードから作成したデータベースを分析する方法については、Analyzing your code with CodeQL queries を参照してください。