CodeQL-Analyse
Unterstützte Sprachen: Python, JavaScript/TypeScript, Go, Java/Kotlin, C/C++, C#, Ruby, Swift.
Skill-Ressourcen: Referenzdateien und Vorlagen befinden sich unter {baseDir}/references/ und {baseDir}/workflows/.
Wesentliche Grundsätze
-
Datenbankqualität ist nicht verhandelbar. Eine Datenbank, die erstellt wird, ist nicht automatisch gut – ein zwischengespeicherter Build extrahiert nichts, meldet aber Erfolg.
-
Datenerweiterungen fangen das auf, was CodeQL übersieht. Django-, Spring- und Express-Projekte verpacken Datenbankaufrufe, Request-Parsing und Shell-Ausführungen immer noch in projektspezifischen APIs, die kein ausgeliefertes Modell abdeckt.
-
Explizite Suite-Referenzen verhindern das stillschweigende Verwerfen von Abfragen. Übergeben Sie niemals Paketnamen an
codeql database analyze– jedes Paket wendet mitdefaultSuiteFileversteckte Filter an, die zu keinen Ergebnissen führen können. Generieren Sie immer eine.qls. -
Null Befunde erfordern eine Untersuchung, keinen Jubel. Es kann an schlechter Extraktion, fehlenden Modellen, falschen Paketen oder Suite-Filtern liegen. Führen Sie
{baseDir}/scripts/check_db_quality.pynach dem Build aus, bestätigen Sie, dass{baseDir}/scripts/verify_query_suite.pyfür die verwendete Suite mit Null beendet wurde – die Generierungsskripte führen es aus, rufen Sie es also nur für eine wiederverwendete oder manuell bearbeitete Suite von Hand auf – und geben Sie im Bericht an, dass beide bestanden wurden. -
macOS Apple Silicon erfordert Workarounds für kompilierte Sprachen. Exit-Code 137 ist ein
arm64e/arm64-Konflikt, kein Build-Fehler. Versuchen Sie zuerst Homebrew arm64-Tools oder Rosetta, bevor Sie aufbuild-mode=nonezurückfallen. -
Befolgen Sie die Workflows Schritt für Schritt. Jede Phase blockiert die nächste; das Überspringen der Qualitätsbewertung oder der Datenerweiterungen hinterlässt die Lücke unsichtbar in den Ergebnissen.
Jeder Bash-Aufruf ist eine neue Shell
Nichts wird über einen Bash-Aufruf hinweg übertragen: keine Variablen, keine Arrays, keine Funktionen, die aus build_log.sh sourced wurden. Jeder Block unten, der einen Wert verwendet, muss ihn im selben Block neu setzen. Die Workflows verweisen hierauf, anstatt es zu wiederholen; was sie angeben, ist der spezifische Schaden an dieser Stelle, weil jeder anders und stillschweigend fehlschlägt:
- eine verlorene Funktion lässt
run_loggedmit Exit 127 beenden, was die Build-Leiter als fehlgeschlagene Methode liest und zu--build-mode=nonehinuntergeht, ohne jemals CodeQL aufgerufen zu haben - ein verlorenes Array expandiert zu nichts, sodass jedes
--threat-modelund--model-packs, das der Benutzer gewählt hat, fallen gelassen wird, während der endgültige Bericht sie immer noch als verwendet auflistet - ein verlorener Skalar unter
set -ubricht den Block mitunbound variableab
Ausgabeverzeichnis
Alle generierten Dateien (Datenbank, Build-Logs, Diagnosen, Erweiterungen, Ergebnisse) werden in einem einzigen Ausgabeverzeichnis gespeichert.
- Wenn der Benutzer ein Ausgabeverzeichnis angibt in seiner Eingabeaufforderung, verwenden Sie es als
OUTPUT_DIR. - Wenn nicht angegeben, standardmäßig auf
./static_analysis_codeql_1. Wenn das bereits existiert, erhöhen Sie auf_2,_3usw.
Erstellen Sie in beiden Fällen immer das Verzeichnis mit mkdir -p, bevor Sie Dateien schreiben.
Setzen Sie USER_SPECIFIED_DIR auf den wörtlichen Pfad aus der Eingabeaufforderung des Benutzers, bevor Sie dies ausführen, oder lassen Sie es nicht gesetzt, um automatisch zu erhöhen. Nichts anderes weist es zu.
# Ausgabeverzeichnis auflösen
USER_SPECIFIED_DIR="${USER_SPECIFIED_DIR:-}" # hier den Pfad des Benutzers einsetzen, falls vorhanden
if [ -n "$USER_SPECIFIED_DIR" ]; then
OUTPUT_DIR="$USER_SPECIFIED_DIR"
else
BASE="static_analysis_codeql"
N=1
while [ -e "${BASE}_${N}" ]; do
N=$((N + 1))
done
OUTPUT_DIR="${BASE}_${N}"
fi
mkdir -p "$OUTPUT_DIR"
Das Ausgabeverzeichnis wird einmalig zu Beginn aufgelöst, bevor ein Workflow ausgeführt wird. Alle Workflows erhalten $OUTPUT_DIR und speichern ihre Artefakte dort:
$OUTPUT_DIR/
├── rulesets.txt # Ausgewählte Abfragepakete (protokolliert nach Schritt 3)
├── codeql.db/ # CodeQL-Datenbank (Verzeichnis, das codeql-database.yml enthält)
├── build.log # Build-Protokoll
├── codeql-config.yml # Ausschlusskonfiguration (interpretierte Sprachen)
├── diagnostics/ # Diagnoseabfragen und CSVs
├── extensions/ # Datenerweiterungs-YAMLs
├── raw/ # Ungefilterte Analyseausgabe
│ ├── results.sarif
│ └── run-all.qls | important-only.qls
└── results/ # Endgültige Ergebnisse (gefiltert für important-only, kopiert für run-all)
└── results.sarif
Datenbankerkennung
Eine CodeQL-Datenbank wird durch das Vorhandensein einer codeql-database.yml-Markierungsdatei in ihrem Verzeichnis identifiziert. Wenn Sie nach vorhandenen Datenbanken suchen, sammeln Sie immer alle Übereinstimmungen – es kann mehrere Datenbanken aus früheren Läufen oder für verschiedene Sprachen geben.
Erkennungsbefehl. find_databases.sh gibt einen Datenbankpfad pro Zeile aus und filtert die Markierungsdateien heraus, die ein fehlgeschlagener Build hinterlässt. Erstellen Sie das Array im selben Block, der daraus auswählt – jeder Bash-Aufruf ist eine neue Shell, also ist ein hier erstelltes Array beim nächsten Aufruf leer, und der Lauf schlussfolgert, dass es keine Datenbank gibt:
# Command Substitution, nicht `done < <(...)`: eine Process Substitution verwirft den Exit-Status
# des Skripts, daher würde "codeql is not on this shell's PATH" (Exit 2) als leere Liste ankommen
# und leitet zu "neue Datenbank erstellen", während drei gute auf der Platte liegen.
if ! DB_LIST=$("{baseDir}/scripts/find_databases.sh" "${OUTPUT_DIR:-.}" .); then
echo "FEHLER: Datenbankerkennung fehlgeschlagen — siehe Meldung oben" >&2
exit 1
fi
FOUND_DBS=()
while IFS= read -r db; do
[ -n "$db" ] || continue
FOUND_DBS+=("$db")
done <<<"$DB_LIST"
echo "Gefundene vorhandene Datenbank(en): ${#FOUND_DBS[@]}"
# Die Metadaten, die der Auswahlaufforderung benötigt, hier gesammelt und nicht in einem eigenen
# Block: FOUND_DBS ist beim nächsten Bash-Aufruf weg, und eine Schleife über ein Array, das nicht
# mehr existiert, gibt nichts aus und meldet Erfolg.
for db in "${FOUND_DBS[@]}"; do
CODEQL_LANG=$(codeql resolve database --format=json -- "$db" 2>/dev/null | jq -r '.languages[0]')
CREATED=$(grep '^creationMetadata:' -A5 "$db/codeql-database.yml" 2>/dev/null | grep 'creationTime' | awk '{print $2}')
echo "$db — Sprache: $CODEQL_LANG, erstellt: $CREATED"
done
Gehen Sie niemals davon aus, dass eine Datenbank codeql.db heißt – erkennen Sie sie an ihrer Markierungsdatei.
Wenn mehrere Datenbanken gefunden werden: Verwenden Sie AskUserQuestion, um den Benutzer auswählen zu lassen, welche Datenbank verwendet oder eine neue erstellt werden soll, basierend auf der oben ausgegebenen Sprache und Erstellungszeit. AskUserQuestion akzeptiert maximal vier Optionen; bei mehr Datenbanken bieten Sie die drei aktuellsten plus "Neue Datenbank erstellen" an und listen Sie die restlichen im Aufforderungstext auf. Überspringen Sie AskUserQuestion, wenn der Benutzer in seiner Eingabeaufforderung explizit angegeben hat, welche Datenbank verwendet oder eine neue erstellt werden soll.
Schnellstart
Für den häufigsten Fall ("diese Codebasis auf Schwachstellen scannen"):
# Überprüfen, ob CodeQL installiert ist. Hier anhalten, wenn nicht – jeder spätere Befehl
# schlägt mit einer weniger aussagekräftigen Fehlermeldung fehl, und der Lauf verschwendet
# einen Build-Zyklus, bevor er den Grund nennt.
if ! command -v codeql >/dev/null 2>&1; then
echo "FEHLER: codeql nicht im PATH gefunden. Installieren Sie es mit einem von:" >&2
echo " gh extension install github/gh-codeql # dann: gh codeql install-stub" >&2
echo " brew install --cask codeql" >&2
echo " https://github.com/github/codeql-action/releases (codeql-bundle)" >&2
exit 1
fi
# jq parst `codeql resolve database --format=json` im nächsten Schritt. Ohne es wird
# CODEQL_LANG leer zurückgegeben und der Lauf fährt mit der falschen Sprache fort.
if ! command -v jq >/dev/null 2>&1; then
echo "FEHLER: jq nicht im PATH gefunden (brew install jq / apt install jq)" >&2
exit 1
fi
# uv führt sowohl die Guard-Skripte als auch beide Suite-Generatoren aus. Überprüfen Sie
# es hier und nicht erst bei der Suite-Generierung, die nach dem Build erfolgt – andernfalls
# verbringt ein Rechner ohne uv den gesamten Build, bevor er fehlschlägt.
if ! command -v uv >/dev/null 2>&1; then
echo "FEHLER: uv nicht im PATH gefunden (https://docs.astral.sh/uv/getting-started/)" >&2
exit 1
fi
codeql --version
Dann lösen Sie OUTPUT_DIR mit dem Block in Ausgabeverzeichnis oben auf – es respektiert ein benutzerdefiniertes Verzeichnis, was ein bloßer Auto-Inkrement nicht tut.
Dann führen Sie die vollständige Pipeline aus: Datenbank erstellen → Datenerweiterungen erstellen → Analyse ausführen, indem Sie die folgenden Workflows verwenden.
Abzulehnende Rationalisierungen
Diese Abkürzungen führen zu übersehenen Befunden. Akzeptieren Sie sie nicht:
- "security-extended ist genug" - Es ist die Basis. Überprüfen Sie immer, ob Trail of Bits-Pakete und Community-Pakete für die Sprache verfügbar sind. Sie erfassen Kategorien, die
security-extendedvollständig übersieht. - "security-and-quality ist die breiteste Suite" -
security-and-qualityschließt alleexperimental/Abfragepfade aus. Importieren Sie für den Run-All-Modus sowohlsecurity-and-qualityals auchsecurity-experimental. Die Differenz beträgt je nach Sprache 1–52 Abfragen. - "Die Datenbank wurde erstellt, also ist sie gut" - Eine Datenbank, die erstellt wird, bedeutet nicht, dass sie gut extrahiert wurde. Führen Sie immer eine Qualitätsbewertung durch und überprüfen Sie die Dateianzahl gegen die erwarteten Quelldateien.
- "Datenerweiterungen werden für Standard-Frameworks nicht benötigt" - Selbst Django/Spring-Apps haben benutzerdefinierte Wrapper, die CodeQL nicht modelliert. Das Überspringen von Erweiterungen bedeutet, Schwachstellen zu übersehen.
- "build-mode=none ist für kompilierte Sprachen in Ordnung" - Es produziert eine stark unvollständige Analyse. Nur als absolute letzte Option verwenden. Unter macOS zuerst den arm64-Toolchain-Workaround oder Rosetta versuchen.
- "Der Build schlägt unter macOS fehl, verwenden Sie einfach build-mode=none" - Exit-Code 137 wird durch einen
arm64e/arm64-Konflikt verursacht, nicht durch einen grundlegenden Build-Fehler. Siehe macos-arm64e-workaround.md. - "Keine Befunde bedeutet, der Code ist sicher" - Führen Sie
check_db_quality.pyundverify_query_suite.pyaus und berichten Sie, dass sie bestanden wurden. Ohne sie sind null Befunde und eine Datenbank, die nichts extrahiert hat, die gleiche Ausgabe. - "Ich führe einfach die Standard-Suite aus" / "Ich übergebe einfach die Paketnamen direkt" - Jedes Paket wendet mit
defaultSuiteFileversteckte Filter an und kann zu keinen Ergebnissen führen. Verwenden Sie immer eine explizite Suite-Referenz. - "Ich lege Dateien im aktuellen Verzeichnis ab" - Alle generierten Dateien müssen in
$OUTPUT_DIRabgelegt werden. Das Verstreuen von Dateien im Arbeitsverzeichnis macht die Bereinigung unmöglich und riskiert die Überschreibung früherer Läufe. - "Verwenden Sie einfach die erste Datenbank, die ich finde" - Es können mehrere Datenbanken für verschiedene Sprachen oder aus früheren Läufen existieren. Wenn mehr als eine gefunden wird, präsentieren Sie dem Benutzer alle Optionen. Überspringen Sie die Aufforderung nur, wenn der Benutzer bereits angegeben hat, welche Datenbank verwendet werden soll.
- "Der Benutzer sagte 'scannen', das bedeutet, er möchte, dass ich eine Datenbank auswähle" - "Scannen" ist keine Datenbankauswahl. Wenn mehrere Datenbanken existieren und der Benutzer keine genannt hat, fragen Sie nach.
Workflow-Auswahl
Dieser Skill hat drei Workflows. Sobald ein Workflow ausgewählt ist, führen Sie ihn Schritt für Schritt aus, ohne Phasen zu überspringen.
Diese Läufe sind lang. Ein Datenbank-Build hat vier Fallback-Methoden, verwenden Sie also die Aufgabenwerkzeuge, um den Fortschritt zu verfolgen. Entscheiden Sie basierend auf dem Lauf, welche Schritte eine Verfolgung wert sind.
| Workflow | Zweck |
|---|---|
| build-database | CodeQL-Datenbank unter sequenzieller Verwendung von Build-Methoden erstellen |
| create-data-extensions | Datenerweiterungsmodelle für Projekt-APIs erkennen oder generieren |
| run-analysis | Regelwerke auswählen, Abfragen ausführen, Ergebnisse verarbeiten |
Unbeaufsichtigtes Erstellen
Dieses Plugin liefert /static-analysis:codeql-build, das die Build-Datenbank-Schritte Ende-zu-Ende ausführt: Sprache und Toolchain erkennen, die Methodenleiter durchlaufen und dabei Korrekturen aus build-fixes.md zwischen den Stufen anwenden und die Qualitätsschranke durchsetzen.
/static-analysis:codeql-build {"target": "/abs/path", "lang": "cpp"}
Es fragt nichts. Wenn alle Methoden fehlschlagen und eine Datenbank unterhalb der Qualitätsschwelle erstellt wird, werden diese als Stati zurückgemeldet – no-method-succeeded und built-below-threshold –, damit Sie hier handeln können, da die Entscheidung, ob die verbleibenden Extraktorfehler auf Code beschränkt sind, den niemand analysiert haben muss, eine Beurteilung ist, die der Lauf nicht treffen kann.
Verwenden Sie es, wenn der Build der lange, unsichere Teil ist und Sie ihn zu einem Abschluss bringen möchten. Arbeiten Sie build-database.md von Hand durch, wenn Sie ein Mitspracherecht haben möchten, welche Methode versucht wird, oder wenn ein Build-Fehler während des Auftretens interpretiert werden muss.
Auto-Erkennungslogik
Wenn der Benutzer explizit angibt, was zu tun ist (z.B. "Datenbank erstellen", "Analyse auf ./my-db ausführen"), führen Sie diesen Workflow direkt aus. Rufen Sie NICHT AskUserQuestion für die Datenbankauswahl auf, wenn die Eingabeaufforderung des Benutzers seine Absicht bereits klar macht – z.B. "neue Datenbank erstellen", "die CodeQL-Datenbank in static_analysis_codeql_2 analysieren", "einen vollständigen Scan von Grund auf durchführen".
Standard-Pipeline für "test", "scan", "analyze" oder ähnliches: Entdecken Sie vorhandene Datenbanken mit dem Befehl in Datenbankerkennung oben, entscheiden Sie dann.
| Bedingung | Aktion |
|---|---|
| Keine Datenbanken gefunden | Neues $OUTPUT_DIR auflösen, Build → Erweiterungen → Analyse ausführen (vollständige Pipeline) |
| Eine Datenbank gefunden | AskUserQuestion verwenden: Wiederverwenden oder neu erstellen? |
| Mehrere Datenbanken gefunden | AskUserQuestion verwenden, begrenzt auf vier Optionen – siehe Datenbankerkennung |
| Benutzer hat Absicht explizit angegeben | AskUserQuestion überspringen, direkt nach seinen Anweisungen handeln |
Datenbankauswahlaufforderung
Wenn vorhandene Datenbanken gefunden werden und der Benutzer nicht explizit angegeben hat, welche verwendet werden soll, präsentieren Sie sie via AskUserQuestion unter der Überschrift "Vorhandene CodeQL-Datenbanken". Beschriften Sie jede Option mit dem Pfad, der Sprache und der oben gesammelten Erstellungszeit – ./static_analysis_codeql_1/codeql.db (Sprache: python, erstellt: 2026-02-24) – und machen Sie die letzte Option "Neue Datenbank erstellen".
Nach der Auswahl:
- Wenn der Benutzer eine vorhandene Datenbank auswählt: Setzen Sie
$OUTPUT_DIRauf ihr übergeordnetes Verzeichnis (oder das Verzeichnis, das sie enthält), setzen Sie$DB_NAMEauf den ausgewählten Pfad, fahren Sie dann mit Erweiterungen → Analyse fort. - Wenn der Benutzer "Neu erstellen" auswählt: Lösen Sie ein neues
$OUTPUT_DIRauf, führen Sie Build → Erweiterungen → Analyse aus.
Allgemeine Entscheidungsaufforderung
Wenn weder die Datenbank noch der Workflow aus der Eingabeaufforderung klar hervorgehen, bieten Sie die vier Workflows via `AskUserQue
…
[abgeschnitten für die Übersetzung]