Activer l’analyse du code avec des outils tiers

Effectué

Au lieu d’exécuter l’analyse du code dans GitHub, vous pouvez effectuer l’analyse ailleurs, puis charger les résultats. Les alertes pour l’analyse du code que vous exécutez en externe s’affichent de la même façon que celle que vous exécutez dans GitHub. Vous pouvez charger des fichiers SARIF (Static Analysis Results Interchange Format) générés en dehors de GitHub ou avec GitHub Actions pour voir les alertes d’analyse du code des outils tiers dans votre référentiel.

Dans cette unité, vous apprendrez à activer l’analyse du code avec des outils tiers et à utiliser et à charger des fichiers SARIF.

À propos des chargements de fichiers SARIF pour l’analyse du code

GitHub crée des alertes d’analyse du code dans un référentiel à l’aide des informations des fichiers SARIF. Vous pouvez générer des fichiers SARIF à l’aide de nombreux outils de test de sécurité d’analyse statique, y compris CodeQL. Les résultats doivent utiliser SARIF version 2.1.0.

Vous pouvez charger les résultats à l’aide de l’API d’analyse du code, de l’interface de ligne de commande CodeQL ou de GitHub Actions. La meilleure méthode de chargement dépend de la façon dont vous avez généré le fichier SARIF.

API d’analyse du code

L’API d’analyse du code vous permet de récupérer des informations sur les alertes d’analyse du code, les analyses, les bases de données et la configuration d’installation par défaut depuis un référentiel. En outre, vous pouvez mettre à jour des alertes d’analyse du code et la configuration d’installation par défaut. Vous pouvez utiliser les points de terminaison pour créer des rapports automatisés pour les alertes d’analyse du code dans une organisation ou charger les résultats d’analyse générés à l’aide d’outils d’analyse du code hors connexion.

L’API GitHub est accessible via HTTPS à partir de https://api.github.com. Toutes les données sont envoyées et reçues au format JSON. L’API utilise des types médias personnalisés pour permettre aux consommateurs de choisir le format des données qu’ils souhaitent recevoir. Les types médias sont spécifiques aux ressources, ce qui leur permet de changer de façon indépendante et de prendre en charge des formats que d’autres ressources ne prennent pas en charge.

Il existe un type de média personnalisé pris en charge pour l’API REST d’analyse du code. application/sarif+json

Vous pouvez utiliser ce type média avec les requêtes GET envoyées au point de terminaison /analyses/{analysis_id}. Lorsque vous utilisez ce type média avec cette opération, la réponse comprend un sous-ensemble des données réelles qui ont été chargées pour l’analyse spécifiée, plutôt que le résumé de l’analyse qui est retourné lorsque vous utilisez le type média par défaut. La réponse comprend également des données supplémentaires, telles que les propriétés github/alertNumber et github/alertUrl. Les données sont mises en forme en tant que SARIF version 2.1.0.

Voici un exemple de commande cURL utilisant l’API pour lister les alertes d’analyse du code pour une organisation :

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

Pour plus d’informations sur l’utilisation de l’API d’analyse du code, consultez les documents de l’API REST GitHub .

Interface CLI CodeQL

L’interface CLI CodeQL est un produit autonome que vous pouvez utiliser pour analyser le code. Son objectif principal est de générer une représentation de base de données d’un codebase, une base de données CodeQL. Une fois la base de données prête, vous pouvez l’interroger de manière interactive ou exécuter une suite de requêtes pour générer un ensemble de résultats au format SARIF et charger les résultats dans GitHub.com. L’interface CLI CodeQL est gratuite à utiliser sur les référentiels publics gérés sur GitHub.com, et elle est disponible pour être utilisée sur les référentiels privés appartenant au client avec une licence Advanced Security. Téléchargez le bundle CodeQL à partir de https://github.com/github/codeql-action/releases.

Le bundle contient :

  • Produit CLI CodeQL
  • Une version compatible des requêtes et des bibliothèques de https://github.com/github/codeql
  • Versions précompilées de toutes les requêtes incluses dans le bundle

Vous devriez toujours utiliser le pack CodeQL, car il vous évite tout problème de compatibilité et offre également de meilleures performances qu’un téléchargement séparé de l’interface de ligne de commande CodeQL et de l’extraction des requêtes CodeQL.

Analyse du code avec GitHub Actions

Afin d’utiliser GitHub Actions pour charger un fichier SARIF tiers dans un référentiel, vous avez besoin d’un flux de travail GitHub Actions. Un flux de travail GitHub Actions est un processus automatisé, constitué d’un ou de plusieurs travaux, configuré en tant que fichier .yml. Les flux de travail sont stockés dans le répertoire .github/workflows de votre référentiel.

Votre flux de travail utilise l’action upload-sarif, qui fait partie du référentiel github/codeql-action. Ce flux de travail comprend des paramètres d’entrée que vous pouvez utiliser pour configurer le chargement.

Le paramètre d’entrée principal est sarif-file, qui configure le fichier ou le répertoire des fichiers SARIF à charger. Le chemin du répertoire ou du chemin est relatif à la racine du référentiel.

L’action upload-sarif peut être configurée pour s’exécuter lorsque l’événement push et scheduled se produit.

Cet exemple décrit les éléments du fichier action.yml 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' 

À chaque fois que les résultats d’une nouvelle analyse du code sont chargés, ils sont traités et les alertes sont ajoutées au référentiel. GitHub utilise les propriétés du fichier SARIF pour afficher les alertes. Par exemple, pour empêcher les alertes en double pour le même problème, l’analyse du code utilise des empreintes digitales pour faire correspondre les résultats entre les différentes exécutions afin qu’ils ne s’affichent qu’une seule fois dans la dernière exécution de la branche sélectionnée. Les fichiers SARIF créés par le flux de travail d’analyse CodeQL contiennent ces données d’empreinte digitale dans le champ partialFingerprints. Si vous chargez un fichier SARIF à l’aide de l’action upload-sarif et que ces données sont manquantes, GitHub tente de renseigner le champ partialFingerprints à partir des fichiers sources.

Si votre fichier SARIF n’inclut pas partialFingerprints, l’action upload-sarif calcule le champ partialFingerprints pour vous et tente d’empêcher les alertes en double. GitHub ne peut créer partialFingerprints que lorsque le référentiel contient à la fois le fichier SARIF et le code source utilisé dans l’analyse statique.

Le chargement SARIF prend en charge un maximum de 5 000 résultats par chargement. Tous les résultats au-delà de cette limite sont ignorés. Si un outil génère trop de résultats, vous devez mettre à jour la configuration pour vous concentrer sur les résultats des règles ou requêtes les plus importantes.

Pour chaque chargement, un chargement SARIF prend en charge une taille maximale de 10 Mo pour le fichier SARIF compressé au format gzip. Tous les chargements au-delà de cette limite sont rejetés. Si votre fichier SARIF est trop volumineux parce qu’il contient trop de résultats, vous devez mettre à jour la configuration pour vous concentrer sur les résultats des règles ou requêtes les plus importantes.

Charger les fichiers SARIF générés en dehors de votre référentiel

Vous pouvez également créer un nouveau flux de travail qui charge les fichiers SARIF après leur validation dans votre référentiel. Cela est utile lorsque le fichier SARIF est généré en tant qu’artefact en dehors de votre référentiel.

Dans l’exemple suivant, le flux de travail s’exécute à chaque fois que des validations sont envoyées au référentiel. L’action utilise la propriété partialFingerprints pour déterminer si des modifications ont eu lieu.

En plus de s’exécuter lorsque des validations sont envoyées, le flux de travail est planifié pour s’exécuter une fois par semaine. Ce flux de travail charge le fichier results.sarif situé à la racine du référentiel. Vous pouvez également modifier ce flux de travail pour charger un répertoire de fichiers SARIF. Par exemple, vous pouvez placer tous les fichiers SARIF dans un répertoire à la racine de votre référentiel appelé sarif-output et définir le paramètre d’entrée de l’action sarif_file sur 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 

Charger des fichiers SARIF générés dans le cadre d’un flux de travail d’intégration continue (CI)

Si vous générez votre fichier SARIF tiers dans le cadre d’un flux de travail d’intégration continue (CI), vous pouvez ajouter l’action upload-sarif en tant qu’étape après avoir exécuté vos tests CI. Si vous n’avez pas encore de flux de travail CI, vous pouvez en créer un à l’aide d’un flux de travail de démarrage dans le référentiel https://github.com/actions/starter-workflows.

Dans cet exemple, le flux de travail s’exécute à chaque fois que des validations sont envoyées au référentiel. L’action utilise la propriété partialFingerprints pour déterminer si des modifications ont eu lieu. En plus de s’exécuter lorsque des validations sont envoyées, le flux de travail est planifié pour s’exécuter une fois par semaine.

Cet exemple montre l’outil d’analyse statique ESLint comme étape d’un flux de travail. L’étape Run ESLint exécute l’outil ESLint et génère le fichier results.sarif. Le flux de travail charge ensuite le fichier results.sarif sur GitHub à l’aide de l’action 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
  ```