Verwenden der CodeQL-CLI

Abgeschlossen

Viele der gleichen primären CodeQL-Features können nicht nur über die grafische Benutzeroberfläche auf GitHub.com, sondern auch über eine Befehlszeilenschnittstelle verwendet werden.

In dieser Lerneinheit wird die Verwendung der CodeQL-CLI zum Erstellen und Analysieren von Datenbanken sowie zum Hochladen der Ergebnisse in GitHub behandelt.

CodeQL-CLI-Befehle

Nachdem Sie die CodeQL-CLI für Server in Ihrem CI-System verfügbar gemacht und sichergestellt haben, dass sie sich mit GitHub authentifizieren können, können Sie Daten generieren.

Sie können drei unterschiedliche Befehle verwenden, um Ergebnisse zu generieren und diese auf GitHub hochzuladen:

  • database create: Mit diesem Befehl erstellen Sie eine CodeQL-Datenbank, die die hierarchische Struktur aller unterstützten Programmiersprachen im Repository darstellt.
  • database analyze: Mit diesem Befehl führen Sie Abfragen aus, um jede CodeQL-Datenbank zu analysieren und die Ergebnisse in einer SARIF-Datei zusammenzufassen.
  • github upload-results: Mit diesem Befehl laden Sie die SARIF-Dateien auf GitHub hoch, wo die Ergebnisse mit einem Branch oder Pull Request abgeglichen und als Codeüberprüfungswarnungen angezeigt werden.

Sie können die Befehlszeilenhilfe für jeden Befehl über --help option anzeigen.

Das Hochladen von SARIF-Daten, die als Ergebnisse der Codeüberprüfung auf GitHub angezeigt werden, wird für Repositorys der Organisation mit GitHub Advanced Security sowie öffentliche Repositorys auf GitHub.com unterstützt.

Erstellen von CodeQL-Datenbanken zur Analyse

Führen Sie die folgenden Schritte aus, um CodeQL-Datenbanken zu erstellen, die analysiert werden sollen.

  1. Checken Sie den Code aus, den Sie analysieren möchten:
    • Für einen Zweig: Überprüfen Sie den Kopf des Zweiges, den Sie analysieren möchten.
    • Für einen Pull Request: Checken Sie entweder den Headcommit des Pull Requests oder den von GitHub generierten Mergecommit aus.
  2. Richten Sie die Umgebung für die Codebasis ein, und stellen Sie sicher, dass alle Abhängigkeiten verfügbar sind.
  3. Suchen Sie ggf. den Buildbefehl für die Codebasis. Üblicherweise ist dieser in der Konfigurationsdatei des CI-Systems verfügbar.
  4. Führen Sie codeql database create im Check-Out-Stamm Ihres Repositorys aus, und erstellen Sie die Codebasis:
    • Verwenden Sie den folgenden Befehl, um eine CodeQL-Datenbank für eine einzelne unterstützte Sprache zu erstellen:

      codeql database create <database> --command <build> --language=<language-identifier>
      
    • Führen Sie den folgenden Befehl aus, um eine CodeQL-Datenbank für mehrere unterstützte Sprachen zu erstellen:

      codeql database create <database> --command <build> \
        --db-cluster --language=<language-identifier>,<language-identifier>
      

Hinweis

Wenn Sie einen Containerbuild verwenden, müssen Sie die CodeQL-CLI innerhalb des Containers ausführen, in dem die Buildaufgabe ausgeführt wird.

Die vollständige Liste der Parameter für den Befehl database create ist in der folgenden Tabelle enthalten:

Option Erforderliche Verwendung
<database> Geben Sie den Namen und den Speicherort eines Verzeichnisses an, das für die CodeQL-Datenbank erstellt werden soll. Der Befehl schlägt fehl, wenn Sie versuchen, ein vorhandenes Verzeichnis zu überschreiben. Wenn Sie außerdem --db-cluster angeben, ist dies das übergeordnete Verzeichnis, und für jede analysierte Sprache wird ein Unterverzeichnis erstellt.
--language Geben Sie den Bezeichner für die Sprache an, um eine Datenbank für eine von cpp, csharp, go, java, javascript, python und ruby zu erstellen (verwenden Sie JavaScript zum Analysieren von TypeScript-Code). Wenn es zusammen mit --db-cluster verwendet wird, akzeptiert die Option eine durch Kommas getrennte Liste oder kann mehrmals angegeben werden.
--command Empfohlen. Verwende diese Option, um den Buildbefehl oder das Skript anzugeben, der bzw. das den Buildprozess für die Codebasis aufruft. Befehle werden aus dem aktuellen Ordner oder, wenn dieser definiert ist, aus --source-root ausgeführt. Diese Option ist für Python- und JavaScript- bzw. TypeScript-Analysen nicht erforderlich.
--db-cluster Fakultativ Verwenden Sie diese Option für Codebasen mit mehreren Sprachen, um eine Datenbank für jede durch --language angegebene Sprache zu generieren.
--no-run-unnecessary-builds Empfohlen. Wird verwendet, um den Buildbefehl für Sprachen zu unterdrücken, in denen die CodeQL CLI den Build nicht überwachen muss (z. B. Python und JavaScript/TypeScript).
--source-root Optional. Verwenden Sie diese Option, wenn Sie die CLI außerhalb des Check-Out-Stamms des Repositorys ausführen. Beim Befehl zum Erstellen von Datenbanken wird standardmäßig davon ausgegangen, dass das aktuelle Verzeichnis das Stammverzeichnis der Quelldateien ist. Verwenden Sie diese Option, um einen anderen Speicherort anzugeben.

Beispiel für eine einzelne Sprache

In diesem Beispiel wird eine CodeQL-Datenbank für das Repository erstellt, das unter /checkouts/example-repo ausgecheckt ist. Dabei wird der JavaScript-Extraktor verwendet, um eine hierarchische Darstellung des JavaScript- und TypeScript-Codes im Repository zu erstellen. Die resultierende Datenbank wird unter /codeql-dbs/example-repo gespeichert.

$ 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.

Beispiel für mehrere Sprachen

In diesem Beispiel werden zwei CodeQL-Datenbanken für das Repository erstellt, die unter /checkouts/example-repo-multi ausgecheckt sind. Folgendes wird verwendet:

  • --db-cluster: Wird verwendet, um die Analyse mehrerer Sprachen anzufordern
  • --language: Wird verwendet, um anzugeben, für welche Sprachen Datenbanken erstellt werden sollen
  • --command: Wird verwendet, um dem Tool den Buildbefehl für die Codebasis weiterzugeben.
  • --no-run-unnecessary-builds um dem Tool mitzuteilen, dass der Buildbefehl für Sprachen übersprungen wird, in denen er nicht benötigt wird (z. B. Python).

Die resultierenden Datenbanken werden in den Unterverzeichnissen python und cpp von /codeql-dbs/example-repo-multi gespeichert.

$ 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.
$

Analysieren einer CodeQL-Datenbank

Führen Sie nach dem Erstellen der CodeQL-Datenbank die folgenden Schritte durch, um sie zu analysieren:

  1. Führen Sie optional codeql pack download <packs> aus, um CodeQL-Pakete (Beta) herunterzuladen, die Sie während der Analyse ausführen können.
  2. Führen Sie codeql database analyze auf der Datenbank aus, und geben Sie an, welche Pakete und/oder Abfragen verwendet werden sollen.
codeql database analyze <database> --format=<format> \
    --output=<output>  <packs,queries>

Hinweis

Wenn Sie mehrere CodeQL-Datenbanken für einen einzelnen Commit analysieren, müssen Sie für alle Ergebnisse, die dieser Befehl generiert, eine SARIF-Kategorie angeben. Wenn Sie die Ergebnisse auf GitHub hochladen, wird diese Kategorie bei der Codeüberprüfung verwendet, um die Ergebnisse separat für jede Sprache zu speichern. Wenn Sie dies vergessen, überschreibt jeder Upload die alten Ergebnisse.

codeql database analyze <database> --format=<format> \
    --sarif-category=<language-specifier> --output=<output> \
    <packs,queries>

Die vollständige Liste der Parameter für den Befehl database analyze ist in der folgenden Tabelle enthalten:

Option Vorgeschriebene Nutzung
<database> Geben Sie den Pfad des Verzeichnisses an, das die zu analysierende CodeQL-Datenbank enthält.
<packs,queries> Geben Sie CodeQL-Pakete oder -Abfragen an, die ausgeführt werden sollen. Lassen Sie diesen Parameter aus, um die Standardabfragen zur Codeüberprüfung auszuführen. Die anderen Abfragesammlungen, die im Paket für die CodeQL-CLI enthalten sind, finden Sie unter /<extraction-root>/codeql/qlpacks/codeql-<language>/codeql-suites. Weitere Informationen zum Erstellen einer eigenen Abfragesuite finden Sie unter „Erstellen von CodeQL-Abfragesuites“[5] in der Dokumentation zur CodeQL-CLI.
--format Gib das Format der vom Befehl generierten Ergebnisdatei an. Für den Upload auf GitHub sollte sarif-latest verwendet werden.
--output Geben Sie an, wo die SARIF-Ergebnisdatei gespeichert werden soll.
--sarif-category Diese Option kann optional bei der Analyse einer einzelnen Datenbank verwendet werden. Diese Option ist erforderlich, um die Sprache zu definieren, wenn du mehrere Datenbanken für einen einzelnen Commit in einem Repository analysierst. Gib eine Kategorie an, die in die SARIF-Ergebnisdatei für diese Analyse aufgenommen werden soll. Eine Kategorie wird verwendet, um mehrere Analysen für dasselbe Tool und denselben Commit zu unterscheiden, die jedoch für verschiedene Sprachen oder Teile des Codes ausgeführt werden.
--sarif-add-query-help Optional. Verwende diese Option, wenn du jegliches verfügbare, Markdown-gerendertes Abfragehilfsmaterial für benutzerdefinierte Abfragen, die in deiner Analyse verwendet werden, einzuschließen möchtest. Alle Abfragehilfen für benutzerdefinierte Abfragen, die in der SARIF enthalten sind, werden auf der Benutzeroberfläche für die Codeüberprüfung angezeigt, wenn die entsprechende Abfrage eine Warnung generiert.
<packs> Optional. Verwenden Sie diese Option, wenn Sie CodeQL-Abfragepakete heruntergeladen haben und die in den Paketen angegebenen Standardabfragen oder Abfragesammlungen ausführen möchten.
--threads Optional. Verwenden Sie diese Option, wenn Sie mehrere Threads zum Ausführen von Abfragen verwenden möchten. Der Standardwert ist 1. Sie können weitere Threads angeben, um die Abfrageausführung zu beschleunigen. Geben Sie „0“ an, um die Anzahl der Threads auf die Anzahl der logischen Prozessoren festzulegen.
--verbose Optional. Verwenden Sie diese Option, um weitere Informationen zum Analyseprozess und Diagnosedaten zum Prozess der Datenbankerstellung zu erhalten.

Einfaches Beispiel

In diesem Beispiel wird eine unter /codeql-dbs/example-repo gespeicherte CodeQL-Datenbank analysiert, wobei die Ergebnisse als SARIF-Datei (/temp/example-repo-js.sarif) gespeichert werden. Dabei wird --sarif-category verwendet, um zusätzliche Informationen in die SARIF-Datei einzuschließen, die die Ergebnisse als JavaScript kennzeichnen. Dies ist wichtig, wenn Sie über mehrere CodeQL-Datenbanken verfügen und einen einzelnen Commit in einem Repository analysieren möchten.

$ 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.

Hochladen von Ergebnissen auf GitHub

SARIF-Upload unterstützt maximal 25.000 Ergebnisse pro Upload. Es werden jedoch nur die top 5.000 Ergebnisse angezeigt, die nach Schweregrad priorisiert werden. Wenn ein Tool zu viele Ergebnisse generiert, sollten Sie die Konfiguration aktualisieren, um sich auf die Ergebnisse für die wichtigsten Regeln oder Abfragen zu konzentrieren.

Für jeden Upload unterstützt der SARIF-Upload eine maximale Größe von 10 MB für die mit gzip komprimierte SARIF-Datei. Uploads, die diesen Grenzwert überschreiten, werden abgelehnt. Wenn Ihre SARIF-Datei zu groß ist, weil sie zu viele Ergebnisse enthält, sollten Sie die Konfiguration aktualisieren, um sich auf die Ergebnisse für die wichtigsten Regeln oder Abfragen zu konzentrieren. Weitere Informationen zu Einschränkungen und zur Überprüfung von SARIF-Dateien finden Sie in der Dokumentation[6].

Bevor Sie Ergebnisse auf GitHub hochladen können, müssen Sie bestimmen, wie Sie die GitHub-App oder das zuvor erstellte persönliche Zugriffstoken am besten an die CodeQL CLI übergeben. Es wird empfohlen, den Leitfaden Ihres CI-Systems zur sicheren Verwendung eines Geheimnisspeichers zu lesen. Die CodeQL-CLI unterstützt Folgendes:

  • Verbinden mit einem Geheimnisspeicher mithilfe der Option „--github-auth-stdin“. Dies ist die empfohlene Authentifizierungsmethode.
  • Das Speichern des Geheimnisses in der Umgebungsvariablen GITHUB_TOKEN und das Ausführen der CLI ohne die Option --github-auth-stdin
  • Rufen Sie die Befehlszeilenoption „--github-auth-stdin“ auf und geben Sie über die Standardeingabe ein temporäres Token an. Dies wird zu Testzwecken empfohlen.

Wenn Sie sich für die sicherste und zuverlässigste Methode für Ihren CI-Server entschieden haben, führen Sie codeql github upload-results in jeder SARIF-Ergebnisdatei aus, und schließen Sie --github-auth-stdin ein (es sei denn, das Token ist in der Umgebungsvariablen GITHUB_TOKEN verfügbar).

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

Die vollständige Liste der Parameter für den github upload-results Befehl wird wie folgt in der Tabelle angezeigt.

Option Erforderliche Verwendung
--repository Geben Sie OWNER/NAME (Besitzer/Name) des Repositorys an, in das Daten hochgeladen werden sollen. Der Besitzer muss eine Organisation innerhalb eines Unternehmens sein, die über eine Lizenz für GitHub Advanced Security verfügt. GitHub Advanced Security muss für das Repository aktiviert sein, es sei denn, das Repository ist öffentlich.
--ref Geben Sie den Namen der Referenz an, die Sie ausgecheckt und analysiert haben, damit die Ergebnisse dem richtigen Code zugeordnet werden können. Für einen Branch verwenden Sie refs/heads/BRANCH-NAME. Für den Headcommit eines Pull Requests verwenden Sie refs/pulls/NUMBER/head oder für den von GitHub generierten Mergecommit eines Pull Requests refs/pulls/NUMBER/merge.
--commit Geben Sie die vollständigen SHA des analysierten Commits an.
--sarif Geben Sie die zu ladende SARIF-Datei an.
--github-auth-stdin Fakultativ. Verwenden Sie diese, um der CLI die GitHub-App oder das persönliche Zugriffstoken, das zur Authentifizierung mit der REST-API von GitHub über die Standardeingabe erstellt wurde, zu übergeben. Dies ist nicht erforderlich, wenn der Befehl über Zugriff auf GITHUB_TOKEN-Umgebungsvariablen verfügt, die mit diesem Token festgelegt wurden.