使用 CodeQL CLI

已完成

除了 GitHub.com 上的圖形化使用者介面之外,您也可以透過命令列介面存取許多相同的主要 CodeQL 功能。

本單元將說明如何使用 CodeQL CLI 來建立資料庫、分析資料庫,並將結果上傳至 GitHub。

CodeQL CLI 命令

一旦您將 CodeQL CLI 提供給 CI 系統中的伺服器使用,並確保它們可以使用 GitHub 進行驗證,您就可以開始產生資料。

您可以使用三個不同的命令來產生結果,並將其上傳至 GitHub:

  • database create 建立 CodeQL 資料庫,以代表存放庫中每個支援程式設計語言的階層式結構。
  • database analyze 執行查詢以分析每個 CodeQL 資料庫,並在 SARIF 檔案中摘要說明結果。
  • github upload-results 將產生的 SARIF 檔案上傳至GitHub結果會與分支或提取要求相符,並顯示為程式碼掃描警示。

您可以使用 --help option 顯示任何命令的命令列說明。

GitHub 支援啟用 GitHub Advanced Security 的組織擁有存放庫,以及啟用 GitHub.com 上的公用存放庫,上傳 SARIF 資料以顯示為程式碼掃描結果。

建立 CodeQL 資料庫以進行分析

請遵循下列步驟來建立 CodeQL 資料庫以進行分析。

  1. 簽出您想要分析的程式碼:
    • 對於分支,請簽出您要分析的分支的前端。
    • 對於提取要求,請簽出提取要求的前端認可,或簽出提取要求的 GitHub 產生的合併認可。
  2. 設定程式碼基底的環境,確定有可用的任何相依性。
  3. 尋找程式碼基底的建置命令 (如果有的話)。 一般而言,這可在 CI 系統的組態檔中使用。
  4. 從存放庫的簽出根目錄執行 codeql database create,並建置程式碼基底:
    • 若要為單一支援的語言建立一個 CodeQL 資料庫,請使用下列命令:

      codeql database create <database> --command <build> --language=<language-identifier>
      
    • 若要針對多個支援的語言為每個語言建立一個 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其中一個資料庫(使用 JavaScript 來分析 TypeScript 程式碼)。 搭配 --db-cluster 使用時,選項會接受逗號分隔清單,或可以多次指定。
--command 建議。 用來指定叫用程式碼基底建置程式的建置命令或指令碼。 命令會從目前資料夾執行,或者如果有定義,則從--source-root中執行。 Python 和 JavaScript/TypeScript 分析不需要。
--db-cluster 選擇性。 在多語言程式碼基底中使用,針對 --language 所指定的每個語言產生一個資料庫。
--no-run-unnecessary-builds 建議。 用於隱藏 CodeQL CLI 不需要監視組建的語言建置命令 (例如 Python 和 JavaScript/TypeScript)。
--source-root 選擇性。 如果您在存放庫的簽出根目錄之外執行 CLI,請使用此項目。 依預設,資料庫 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 簽出的存放庫建立兩個 CodeQL 資料庫。 它會使用:

  • --db-cluster 以要求分析多個語言。
  • --language 以指定要用於建立資料庫的語言。
  • --command 以指示工具程式碼基底的建置命令,請在這裡進行。
  • --no-run-unnecessary-builds 指示工具略過不需要的語言建置命令(例如 Python)。

產生的資料庫會儲存在 /codeql-dbs/example-repo-multipythoncpp 子目錄中。

$ 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 套件 (Beta)。
  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 套件或查詢。 若要執行用於程式碼掃描的標準查詢,請省略此參數。 您可以在 /<extraction-root>/codeql/qlpacks/codeql-<language>/codeql-suites 中查看 CodeQL CLI 套件組合中包含的其他查詢套件。 如需建立您自己的查詢套件的相關資訊,請參閱 CodeQL CLI 文件中的建立 CodeQL 查詢套件[5]
--format 指定命令所產生的結果檔案的格式。 若要上傳至 GitHub,這應該是:sarif-latest
--output 指定要儲存 SARIF 結果檔案的位置。
--sarif-category 單一資料庫分析的選擇性。 當您分析存放庫中單一認可的多個資料庫時,必須定義語言。 針對此分析,指定要包含在 SARIF 結果檔案中的類別。 類別可用來區分相同工具和認可的多個分析,但在不同語言或程式碼的不同部分上執行。
--sarif-add-query-help 選擇性。 如果您想要針對分析中使用的自訂查詢包含任何可用的 Markdown 轉譯查詢說明,請使用此參數。 如果相關查詢產生警示,則 SARIF 輸出中所含自訂查詢的任何查詢說明都會顯示在程式碼掃描 UI 中。
<packs> 選擇性。 如果您已下載 CodeQL 查詢套件,而且想要執行套件中指定的預設查詢或查詢套件,請使用此參數。
--threads 選擇性。 如果您想要使用一個以上的執行緒來執行查詢,請使用此參數。 預設值是 1。 您可以指定更多執行緒來加速查詢執行。 若要將執行緒數目設定為邏輯處理器數目,請指定 0。
--verbose 選擇性。 用於從資料庫建立程式取得分析程式和診斷資料的詳細資訊。

基本範例

此範例會分析儲存在 /codeql-dbs/example-repo 的 CodeQL 資料庫,並將結果儲存為 SARIF 檔案:/temp/example-repo-js.sarif。 其會使用 --sarif-category 在 SARIF 檔案中包含額外的資訊,以將結果識別為 JavaScript。 當您有多個 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 中,並執行 CLI 而不包含 --github-auth-stdin 選項。
  • 傳遞 --github-auth-stdin 命令列選項,並透過標準輸入提供暫時性權杖。 建議用於測試目的。

當您決定 CI 伺服器最安全且可靠的方法時,請在每個 SARIF 結果檔案上執行 codeql github upload-results,並包含 --github-auth-stdin,除非環境變數 GITHUB_TOKEN 中提供權杖。

# 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 指定您簽出並分析的 ref 名稱,以便將結果比對到正確的程式碼。 對於分支,請使用 refs/heads/BRANCH-NAME;對於提取要求的前端認可,請使用 refs/pulls/NUMBER/head;或者,對於由 GitHub 所產生提取要求的合併認可,請使用 refs/pulls/NUMBER/merge
--commit 指定您所分析認可的完整 SHA。
--sarif 指定要載入的 SARIF 檔案。
--github-auth-stdin 選擇性。 用來透過標準輸入傳遞 CLI GitHub 應用程式或個人存取權杖,以向 GitHub 的 REST API 進行驗證。 如果命令具有使用此權杖設定的 GITHUB_TOKEN 環境變數存取權,則不需要這樣做。