使用協力廠商工具來啟用程式碼掃描
您可以在其他位置執行分析,然後上傳結果,而不是在 GitHub 中執行程式碼掃描。 您在外部執行程式碼掃描時所產生的警示,會以與您在 GitHub 內執行程式碼掃描的相同方式顯示。 您可以上傳 GitHub 外部或使用 GitHub Actions 產生的靜態分析結果交換格式 (SARIF),以查看存放庫中來自協力廠商工具的程式碼掃描警示。
在本單元中,您將了解如何使用協力廠商工具啟用程式碼掃描,以及如何使用和上傳 SARIF 檔案。
關於 SARIF 檔案上傳以進行程式碼掃描
GitHub 會使用 SARIF 檔案中的資訊,在存放庫中建立程式碼掃描警示。 您可以使用許多靜態分析安全性測試工具 (包括 CodeQL) 來產生 SARIF 檔案。 結果必須使用 SARIF 2.1.0 版。
您可以使用程式碼掃描 API、CodeQL CLI 或 GitHub Actions 來上傳結果。 最佳上傳方法將取決於您產生 SARIF 檔案的方式。
程式碼掃描 API
程式碼掃描 API 可讓您從存放庫擷取程式碼掃描警示、分析、資料庫和預設設定組態的相關資訊。 您也可以更新程式碼掃描警示和預設設定組態。 您可以使用端點,為組織中的程式碼掃描警示建立自動化報告,或上傳使用離線程式碼掃描工具產生的分析結果。
您可以從 https://api.github.com 透過 HTTPS 存取 GitHub API。 所有資料都會以 JSON 形式傳送和接收。 API 會使用自訂媒體類型,讓取用者選擇想要接收的資料格式。 媒體類型是資源特有的類型,可讓其獨立變更,並支援其他資源不支援的格式。
程式代碼掃描 REST API 支援一種自訂的媒體類型。 application/sarif+json
您可以使用此媒體類型搭配傳送至 /analyses/{analysis_id} 端點的 GET 要求。 當您使用此媒體類型搭配此作業時,回應會包括針對所指定分析上傳的實際資料子集,而不是使用預設媒體類型時傳回的分析摘要。 回應也包括其他資料,例如 github/alertNumber 和 github/alertUrl 屬性。 資料會格式化為 SARIF 2.1.0 版。
以下是使用 API 列出組織程式碼掃描警示的範例 cURL 命令:
curl -L \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer <YOUR-TOKEN>" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/orgs/ORG/code-scanning/alerts
如需使用程式碼掃描 API 的詳細資訊,請參閱 GitHub REST API 文件。
CodeQL CLI
CodeQL CLI 是您可以用來分析程式碼的獨立產品。 其主要目的是產生程式碼基底 (CodeQL 資料庫) 的資料庫表示法。 資料庫準備就緒后,您可以以互動方式查詢,也可以執行一組查詢,以 SARIF 格式產生一組結果,並將結果上傳至 GitHub.com。 CodeQL CLI 可免費用於維護於 GitHub.com 上的公用存放庫,並且需要進階安全性授權才能用於客戶擁有的私人存放庫。 從 https://github.com/github/codeql-action/releases 下載 CodeQL 套件組合。
此套件組合包含:
- CodeQL CLI 產品
- 來自 https://github.com/github/codeql 的查詢和程式庫相容版本
- 套件組合中所含全部查詢的預先編譯版本
您應該一律使用 CodeQL 套件組合,因為這可確保相容性,也提供比個別下載 CodeQL CLI 和簽出 CodeQL 查詢更好的效能。
使用 GitHub Actions 進行程式碼掃描分析
若要使用 GitHub Actions 將協力廠商 SARIF 檔案上傳至存放庫,您需要GitHub Actions 工作流程。 GitHub Actions 工作流程是由一或多個作業所組成的自動化流程,設定為 .yml 檔案。 工作流程會儲存在存放庫的 .github/workflows 目錄中。
您的工作流程會使用 upload-sarif 動作,其是 github/codeql-action 存放庫的一部分。 此工作流程包括您可以用來設定上傳的輸入參數。
主要輸入參數是 sarif-file,其會設定要上傳的 SARIF 檔案或其目錄。 目錄或檔案路徑相對於存放庫的根目錄。
upload-sarif 動作可以設定為在 push 和 scheduled 事件發生時執行。
此範例概述 upload-sarif 動作 yml 檔案的元素:
name: 'Code Scanning : Upload SARIF'
description: 'Upload the analysis results'
author: 'GitHub'
inputs:
sarif_file:
description: |
The SARIF file or directory of SARIF files to be uploaded to GitHub code scanning.
See https://docs.github.com/en/code-security/code-scanning/integrating-with-code-scanning/
uploading-a-sarif-file-to-github#uploading-a-code-scanning-analysis-with-github-actions
for information on the maximum number of results and maximum file size supported by code scanning.
required: false
default: '../results'
checkout_path:
description: "The path at which the analyzed repository was checked out.
Used to relativize any absolute paths in the uploaded SARIF file."
required: false
default: ${{ github.workspace }}
token:
default: ${{ github.token }}
matrix:
default: ${{ toJson(matrix) }}
category:
description: String used by Code Scanning for matching the analyses
required: false
wait-for-processing:
description: If true, the Action will wait for the uploaded SARIF to be processed before completing.
required: true
default: "false"
runs:
using: 'node12'
main: '../lib/upload-sarif-action.js'
每次上傳新程式碼掃描的結果時,都會處理這些結果並將警示新增至存放庫。 GitHub 會使用 SARIF 檔案中的屬性來顯示警示。 例如,為了防止相同問題的重複警示,程式碼掃描會使用指紋來比對各種執行的結果,以便其只會在所選分支的最新執行中出現一次。 CodeQL 分析工作流程所建立的 SARIF 檔案會在 partialFingerprints 欄位中包括此指紋資料。 如果您使用 upload-sarif 動作上傳 SARIF 檔案,而且此資料遺漏,GitHub 會嘗試從來源檔案填入 partialFingerprints 欄位。
如果您的 SARIF 檔案未包括 partialFingerprints,upload-sarif 動作會為您計算 partialFingerprints 欄位,並嘗試防止重複的警示。 只有在存放庫同時包含 SARIF 檔案和靜態分析中使用的原始程式碼時,GitHub 才能建立 partialFingerprints。
SARIF 上傳支援每個上傳最多 5,000 個結果。 系統會忽略超過此限制的任何結果。 如果工具產生太多結果,您應該更新設定,以專注於最重要的規則或查詢的結果。
針對每個上傳,SARIF 上傳支援 gzip 壓縮 SARIF 檔案的大小上限為 10 MB。 任何超過此限制的上傳都會遭到拒絕。 如果您的 SARIF 檔案因為包含太多結果而太大,您應該更新設定,以專注于最重要的規則或查詢的結果。
上傳存放庫外部產生的 SARIF 檔案
您也可以建立新的工作流程,在將 SARIF 檔案認可至存放庫之後將其上傳。 當產生 SARIF 檔案作為存放庫外部的成品時,這會很有用。
在下列範例中,每當認可推送至存放庫時,工作流程就會執行。 動作會使用 partialFingerprints 屬性來判斷是否已發生變更。
除了在推送認可時執行,工作流程也會排定每週執行一次。 此工作流程會上傳位於存放庫根目錄的 results.sarif 檔案。 您也可以修改此工作流程來上傳 SARIF 檔案的目錄。 例如,您可以將所有 SARIF 檔案放在存放庫根目錄中稱為 sarif-output 的目錄中,並將動作的輸入參數 sarif_file 設定為 sarif-output。
name: "Upload SARIF"
// Run workflow each time code is pushed to your repository and on a schedule.
//The scheduled workflow runs every Thursday at 15:45 UTC.
on:
push:
schedule:
- cron: '45 15 * * 4'
jobs:
build:
runs-on: ubuntu-latest
permissions:
security-events: write
steps:
# This step checks out a copy of your repository.
- name: Checkout repository
uses: actions/checkout@v2
- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@v1
with:
# Path to SARIF file relative to the root of the repository
sarif_file: results.sarif
上傳作為 CI 工作流程一部分所產生的 SARIF 檔案
如果您產生協力廠商 SARIF 檔案,作為持續整合 (CI) 工作流程的一部分,則可以在執行 CI 測試之後,將 upload-sarif 動作新增為步驟。 如果還沒有 CI 工作流程,您可以使用 https://github.com/actions/starter-workflows 存放庫中的入門工作流程來建立一個。
在此範例中,每當認可推送至存放庫時,工作流程就會執行。 動作會使用 partialFingerprints 屬性來判斷是否已發生變更。 除了在推送認可時執行,工作流程也會排定每週執行一次。
此範例會將 ESLint 靜態分析工具顯示為工作流程中的步驟。
Run ESLint 步驟會執行 ESLint 工具並輸出 results.sarif 檔案。 工作流程接著會使用 results.sarif 動作將 upload-sarif 檔案上傳至GitHub。
```
name: "ESLint analysis"
// Run workflow each time code is pushed to your repository and on a schedule.
// The scheduled workflow runs every Wednesday at 15:45 UTC.
on:
push:
schedule:
- cron: '45 15 * * 3'
jobs:
build:
runs-on: ubuntu-latest
permissions:
security-events: write
steps:
- uses: actions/checkout@v2
- name: Run npm install
run: npm install
// Runs the ESlint code analysis
- name: Run ESLint
// eslint exits 1 if it finds anything to report
run: node_modules/.bin/eslint build docs lib script spec-main -f node_modules/@microsoft/eslint-formatter-sarif/sarif.js -o results.sarif || true
// Uploads results.sarif to GitHub repository using the upload-sarif action
- uses: github/codeql-action/upload-sarif@v1
with:
// Path to SARIF file relative to the root of the repository
sarif_file: results.sarif
```