Abilitare l'analisi del codice con strumenti di terze parti

Completato

Invece di eseguire l'analisi del codice in GitHub, è possibile eseguire l'analisi altrove e quindi caricare i risultati. Gli avvisi per l'analisi del codice eseguiti esternamente vengono visualizzati nello stesso modo di quelli eseguiti all'interno di GitHub. È possibile caricare file SARIF (Static Analysis Results Interchange Format) generati all'esterno di GitHub o con GitHub Actions per visualizzare gli avvisi di analisi del codice da strumenti di terze parti nel repository.

In questa unità si apprenderà come abilitare l'analisi del codice con strumenti di terze parti e come usare e caricare file SARIF.

Informazioni sui caricamenti di file SARIF per l'analisi del codice

GitHub crea avvisi di analisi del codice in un repository usando le informazioni dei file SARIF. È possibile generare file SARIF usando molti strumenti di test di sicurezza dell'analisi statica, tra cui CodeQL. I risultati devono usare SARIF versione 2.1.0.

È possibile caricare i risultati usando l'API di analisi del codice, CodeQL CLI o GitHub Actions. Il metodo di caricamento migliore dipende dalla modalità di generazione del file SARIF.

API di analisi del codice

L'API di analisi del codice consente di recuperare da un repository le informazioni sugli avvisi di analisi del codice, le analisi, i database e la configurazione predefinita. In aggiunta, è possibile aggiornare gli avvisi di analisi del codice e la configurazione di installazione predefinita. È possibile usare gli endpoint per creare report automatizzati per gli avvisi di analisi del codice in un'organizzazione o caricare i risultati dell'analisi generati usando strumenti di analisi del codice offline.

È possibile accedere all'API GitHub tramite HTTPS da https://api.github.com. Tutti i dati vengono inviati e ricevuti come JSON. L'API usa tipi di supporti personalizzati per consentire ai consumer di scegliere il formato dei dati che vogliono ricevere. I tipi di supporto sono specifici per le risorse, ed è quindi possibile modificarli in modo indipendente e supportare formati non supportati da altre risorse.

Esiste un tipo di media personalizzato supportato per l'API REST di analisi del codice, application/sarif+json.

È possibile usare questo tipo di supporto con le richieste GET inviate all'endpoint /analyses/{analysis_id}. Quando si usa questo tipo di supporto con questa operazione, la risposta include un subset dei dati effettivi caricati per l'analisi specificata, anziché il riepilogo dell'analisi restituito quando si usa il tipo di supporto predefinito. La risposta include anche dati aggiuntivi, ad esempio le proprietà github/alertNumber e github/alertUrl. I dati vengono formattati come SARIF versione 2.1.0.

Di seguito, è riportato un esempio di comando cURL che utilizza l'API per elencare gli avvisi di analisi del codice per un'organizzazione:

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

Per altre informazioni sull'uso dell'API di analisi del codice, vedere la documentazione dell'API REST di GitHub .

CodeQL CLI

CodeQL CLI è un prodotto autonomo che è possibile usare per analizzare il codice. Lo scopo principale consiste nel generare una rappresentazione del database di una codebase, un database CodeQL. Quando il database è pronto, è possibile eseguire query in modo interattivo oppure eseguire una suite di query per generare un set di risultati in formato SARIF e caricare i risultati in GitHub.com. L'interfaccia della riga di comando di CodeQL è gratuita da usare nei repository pubblici gestiti in GitHub.com ed è disponibile per l'uso nei repository privati di proprietà del cliente con una licenza di sicurezza avanzata. Scaricare il pacchetto di CodeQL da https://github.com/github/codeql-action/releases.

Il pacchetto contiene:

  • Prodotto CodeQL
  • Una versione compatibile delle query e delle librerie da https://github.com/github/codeql
  • Versioni precompilate di tutte le query incluse nel pacchetto

È consigliabile usare sempre il pacchetto di CodeQL perché garantisce la compatibilità e offre anche prestazioni decisamente migliori rispetto a un download separato di CodeQL CLI e all'estrazione delle query di CodeQL.

Analisi del codice con GitHub Actions

Per usare GitHub Actions per caricare un file SARIF di terze parti in un repository, è necessario un flusso di lavoro GitHub Actions. Un flusso di lavoro GitHub Actions è un processo automatizzato, costituito da uno o più processi, configurati come file.yml. I flussi di lavoro vengono archiviati nella directory .github/workflows per il repository.

Il flusso di lavoro usa l'azione upload-sarif, che fa parte del repository github/codeql-action. Questo flusso di lavoro include parametri di input che possono essere usati per configurare il caricamento.

Il parametro di input principale è sarif-file, che configura il file o la directory dei file SARIF da caricare. La directory o il percorso del file è relativo alla radice del repository.

L'azione upload-sarif può essere configurata per l'esecuzione quando si verifica l'evento push e scheduled.

In questo esempio vengono delineati gli elementi del file UML dell'azione upload-sarif:

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' 

Ogni volta che vengono caricati i risultati di una nuova analisi del codice, i risultati vengono elaborati e gli avvisi vengono aggiunti al repository. GitHub usa le proprietà nel file SARIF per visualizzare gli avvisi. Per evitare ad esempio avvisi duplicati per lo stesso problema, l'analisi del codice usa le impronte digitali per trovare le corrispondenze tra varie esecuzioni in modo che vengano visualizzate una sola volta nell'ultima esecuzione per il ramo selezionato. I file SARIF creati dal flusso di lavoro di analisi di CodeQL includono questi dati di impronta digitale nel campo partialFingerprints. Se si carica un file SARIF usando l'azione upload-sarif e questi dati non sono presenti, GitHub prova a popolare il campo partialFingerprints dai file di origine.

Se il file SARIF non include partialFingerprints, l'azione upload-sarif calcolerà automaticamente il campo partialFingerprints e proverà a impedire avvisi duplicati. GitHub può creare partialFingerprints solo quando il repository contiene sia il file SARIF che il codice sorgente usato nell'analisi statica.

Il caricamento SARIF supporta un massimo di 5.000 risultati per caricamento. Tutti i risultati oltre questo limite vengono ignorati. Se uno strumento genera troppi risultati, è necessario aggiornare la configurazione in modo da concentrarsi sui risultati per le regole o le query più importanti.

Per ogni caricamento, il caricamento SARIF supporta una dimensione massima di 10 MB per il file SARIF con compressione gzip. Eventuali caricamenti oltre questo limite verranno rifiutati. Se il file SARIF è troppo grande perché contiene troppi risultati, è necessario aggiornare la configurazione in modo da concentrarsi sui risultati per le regole o le query più importanti.

Caricare file SARIF generati all'esterno del repository

È anche possibile creare un nuovo flusso di lavoro che carica i file SARIF dopo il commit nel repository. Questo approccio risulta utile quando il file SARIF viene generato come artefatto all'esterno del repository.

Nell'esempio seguente il flusso di lavoro viene eseguito ogni volta che viene eseguito il push dei commit nel repository. L'azione usa la proprietà partialFingerprints per determinare se sono state apportate modifiche.

Oltre all'esecuzione quando viene eseguito il push dei commit, il flusso di lavoro viene pianificato per l'esecuzione una volta alla settimana. Questo flusso di lavoro carica il file results.sarif che si trova nella radice del repository. È anche possibile modificare questo flusso di lavoro per caricare una directory di file SARIF. È ad esempio possibile inserire tutti i file SARIF in una directory nella radice del repository denominato sarif-output e impostare il parametro di input sarif_file dell'azione su 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 

Caricare file SARIF generati come parte di un flusso di lavoro di integrazione continua

Se si genera un file SARIF di terze parti come parte di un flusso di lavoro di integrazione continua, è possibile aggiungere l'azione upload-sarif come passaggio dopo l'esecuzione dei test di integrazione continua. Se non si ha già un flusso di lavoro di integrazione continua, è possibile crearne uno usando un flusso di lavoro iniziale nel repository https://github.com/actions/starter-workflows.

In questo esempio il flusso di lavoro viene eseguito ogni volta che viene eseguito il push dei commit nel repository. L'azione usa la proprietà partialFingerprints per determinare se sono state apportate modifiche. Oltre all'esecuzione quando viene eseguito il push dei commit, il flusso di lavoro viene pianificato per l'esecuzione una volta alla settimana.

Questo esempio mostra lo strumento di analisi statica ESLint come passaggio in un flusso di lavoro. Il passaggio Run ESLint esegue lo strumento ESLint e restituisce il file results.sarif. Il flusso di lavoro carica quindi il file results.sarif in GitHub usando l'azione upload-sarif.

  ```
  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
  ```