Codeanalyse2026-10-13

SAST und CodeQL mit KI: Einsatz und Grenzen

Statische Codeanalyse findet Schwachstellen, bevor der Code läuft. In der Praxis bremst sie meist nicht die Erkennung aus, sondern die Menge der Meldungen. Sprachmodelle (LLMs) setzen genau dort an: bei Spezifikationen, Triage und Korrekturvorschlägen. Dieser Artikel zeigt, wie SAST und CodeQL arbeiten, was die Kombination mit KI belegbar verbessert und wo Lizenz, Fehlalarme und Modellrisiken Grenzen setzen.

Was SAST prüft und was CodeQL anders macht

SAST (Static Application Security Testing) analysiert Quellcode oder Zwischenformen, ohne das Programm auszuführen. Einfache Werkzeuge suchen Muster, etwa den Aufruf einer unsicheren Funktion. Sie erkennen nicht, ob nicht vertrauenswürdige Eingaben diese Stelle überhaupt erreichen.

Taint-Tracking, eine Form der Datenflussanalyse, schließt diese Lücke. Sie verfolgt Werte von Quellen (Eingaben von außen) zu Senken (sicherheitsrelevante Operationen wie eine SQL-Ausführung). Eine Barriere oder ein Sanitizer auf dem Weg unterbricht den Fluss.

CodeQL geht beim Aufbau anders vor als ein Mustersuchwerkzeug. Beim Erzeugen der Datenbank extrahiert es Syntaxbaum, Kontrollfluss und Typinformationen in eine relationale Datenbank je Sprache. Abfragen schreiben Sie in QL, einer deklarativen, objektorientierten Logiksprache (Avgustinov et al., ECOOP 2016). Dieselbe Datenbank beantwortet beliebig viele Abfragen.

Laut CodeQL-Dokumentation deckt CodeQL C/C++, C#, Go, Java, Kotlin, JavaScript, TypeScript, Python, Ruby, Rust, Swift und GitHub Actions ab. Bei kompilierten Sprachen braucht die Extraktion Zugriff auf den Build. Welche Sprachen ohne Build auskommen, steht in der aktuellen CodeQL-Dokumentation.

Vom Code zum FixAblauf von Quellcode über Extraktion, CodeQL-Datenbank und Queries zu SARIF-Alerts, danach optional LLM-Triage und Autofix, Pull Request und Re-Scan, der prüft, ob der Alert verschwindet.QuellcodeRepository, BranchExtraktionParser, BuildCodeQL-DatenbankrelationalQueriesSuite oder eigeneQueries laufen gegen die DatenbankSARIF-AlertsPfad Quelle zu SenkeLLM-TriageoptionalAutofixoptionalPull RequestReview, MergeRe-Scan prüft, ob der Alert verschwindet
Abbildung 1. Vom Code zum Fix. Gestrichelte Kästen sind optionale Stufen, die KI einführt. Der Re-Scan schließt die Schleife.

Taint-Analyse am Beispiel

Das folgende Beispiel ist generisch und stammt aus keinem Kundenprojekt. Die erste Variante baut die SQL-Abfrage per String zusammen. Die zweite übergibt den Wert als Parameter.

Python, generisches Beispiel
# anfällig: Eingabe landet im SQL-Stringdef get_order(request, cursor):    order_id = request.args["id"]                          # Quelle    sql = f"SELECT * FROM orders WHERE id = {order_id}"    # Zusammenbau    cursor.execute(sql)                                    # Senke # behoben: Wert wird gebunden, nicht eingefügtdef get_order(request, cursor):    order_id = request.args["id"]    cursor.execute("SELECT * FROM orders WHERE id = %s", (order_id,))

Der Platzhalter %s hängt vom Datenbanktreiber ab. Andere Treiber nutzen ? oder benannte Parameter.

Derselbe Eingabewert, zwei WegeTaint-Fluss: Die Quelle request.args führt auf dem oberen Pfad über einen String-Zusammenbau ohne Barriere zur Senke cursor.execute und erzeugt einen Alert. Auf dem unteren Pfad bindet die Parameterbindung den Wert als Parameter, dort entsteht kein Alert.Quellerequest.args['id']Zusammenbauf-String {order_id}Parameterbindungexecute(sql, (id,))Senkecursor.execute(sql)keine Barriere: AlertBarriere: kein Alert
Abbildung 2. Derselbe Eingabewert, zwei Wege. Nur der Pfad ohne Barriere erreicht die Senke als Text und löst den Alert aus.

In QL beschreibt eine Abfrage Quellen und Senken und lässt die Bibliothek den Fluss berechnen. Die folgende Abfrage ist verkürzt und dient der Illustration. Die Standard-Suiten enthalten die Abfrage bereits. Eigene Abfragen kommen für interne Frameworks in Frage, deren Quellen und Senken die Standardmodelle nicht kennen.

QL, vereinfachtes Beispiel
/** * @name SQL-Abfrage aus Benutzereingabe (Beispiel) * @kind path-problem * @id example/sql-injection */import pythonimport semmle.python.Conceptsimport semmle.python.dataflow.new.DataFlowimport semmle.python.dataflow.new.TaintTrackingimport semmle.python.dataflow.new.RemoteFlowSources module SqlConfig implements DataFlow::ConfigSig {  predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }  predicate isSink(DataFlow::Node sink) { sink = any(SqlExecution e).getSql() }} module SqlFlow = TaintTracking::Global<SqlConfig>;import SqlFlow::PathGraph from SqlFlow::PathNode source, SqlFlow::PathNode sinkwhere SqlFlow::flowPath(source, sink)select sink.getNode(), source, sink, "SQL-Abfrage aus $@.", source.getNode(), "Benutzereingabe"

Warum klassisches SAST ausbremst

Die IRIS-Studie (ICLR 2025) benennt zwei Ursachen, die auch CodeQL treffen. Beide lassen sich an konkreten Mechanismen festmachen.

Fehlende Spezifikationen für Bibliotheken

Taint-Analyse braucht Modelle: Welche Methode liefert Eingaben, welche ist eine Senke, welche reinigt Werte? Für Drittbibliotheken fehlen diese Angaben oft. Das Ergebnis sind False Negatives, also Schwachstellen ohne Alert.

Fehlender Kontext

Auch bei vollständigen Spezifikationen fehlt der Analyse das Verständnis für Bedingungen, Validierung und Absicht. Das erzeugt Fehlalarme. Entwickler müssen viele potenziell falsche Meldungen durchsehen und verlieren dabei Zeit.

Grenzen der Methode

Statische Analyse nähert Programmverhalten an. Exakt ist das im Allgemeinen nicht berechenbar (Satz von Rice). Reflection, dynamische Auflösung und Konfiguration zur Laufzeit machen Flüsse schwer verfolgbar. Auch Fehler in der Geschäftslogik, etwa fehlende Autorisierungsprüfungen, lassen sich kaum als Quelle-Senke-Muster ausdrücken.

Was LLMs verändern

LLMs ersetzen die Analyse nicht. Sie ergänzen sie an den Stellen, an denen Regeln fehlen oder Kontext nötig ist. Vier Einsatzstellen sind dokumentiert.

Spezifikationen ableiten

IRIS lässt ein Modell Quellen und Senken aus Bibliotheks-APIs ableiten und gibt sie an CodeQL weiter. Auf dem Benchmark CWE-Bench-Java fand IRIS mit GPT-4 55 Schwachstellen, CodeQL allein 27.

Alerts bewerten

Das Modell erhält den Codepfad samt Umgebung und urteilt, ob der Alert echt ist.

Korrekturen vorschlagen

Copilot Autofix erzeugt Korrekturen zu CodeQL-Alerts. GitHub nennt für die Beta-Phase mehr als 90 % abgedeckte Alert-Typen in JavaScript, TypeScript, Java und Python. Mehr als zwei Drittel der Funde ließen sich mit wenig oder keiner Nacharbeit beheben. Das ist eine Herstellerangabe.

Agentisch arbeiten

Seit Juli 2026 gibt es Agentic Autofix als Public Preview. Es untersucht die Codebasis und prüft den Fix durch einen erneuten CodeQL-Lauf. Es verbraucht AI Credits und Actions-Minuten. Ob zusätzlich Tests laufen, nennt die Ankündigung nicht.

Die Triage verlagert sich vom Menschen auf das ModellGegenüberstellung. Klassisch: alle Alerts, manuelle Triage jedes Alerts, Fix von Hand. Hybrid: alle Alerts, LLM-Triage mit Begründung, Prüfung und Fix-Vorschlag mit Stichprobe der verworfenen Alerts. Risiko links: Aufwand wächst mit der Alertzahl. Risiko rechts: Fehlurteile können echte Funde verwerfen.KlassischHybrid mit LLMAlle AlertsMuster- und DatenflussfundeManuelle Triagejeder Alert wird von Hand geprüftFix von HandEntwickler schreibt die KorrekturAlle AlertsMuster- und DatenflussfundeLLM-TriageVerdikt mit Begründung und KontextPrüfung und Fix-VorschlagReview plus Stichprobe der VerworfenenAufwand wächst mit der AlertzahlFehlurteile können echte Funde verwerfen
Abbildung 3. Die Triage verlagert sich vom Menschen auf das Modell. Dafür kommt ein neues Risiko hinzu, das die Stichprobe der verworfenen Alerts abfangen soll.

Wie belastbar sind die Zahlen?

AussageQuelleEinstufung
55 statt 27 gefundene Schwachstellen auf CWE-Bench-JavaIRIS, ICLR 2025begutachtet
False Discovery Rate 84,82 %, 5,21 Prozentpunkte unter CodeQLIRIS, ICLR 2025begutachtet
Mehr als 90 % der Alert-Typen, rund zwei Drittel ohne oder mit wenig NacharbeitGitHub BlogHerstellerangabe
Verbesserte Fehlalarmerkennung mit Gedächtnis aus früheren Alerts (Memoir)arXiv-PreprintPreprint
91 % weniger Fehlalarme (225 auf 20) gegenüber Semgrep allein (SAST-Genius)arXiv-PreprintPreprint

Die IRIS-Ergebnisse stammen aus einem Java-Benchmark mit bekannten Schwachstellen. Sie sagen nichts über beliebige Unternehmensanwendungen aus. Die Preprints sind nicht unabhängig geprüft.

Einsatz in der Pipeline

CodeQL läuft typischerweise in der CI und meldet Ergebnisse im SARIF-Format als Code-Scanning-Alerts. Bei Pull Requests erscheinen die Funde direkt am Diff. Das folgende Workflow-Beispiel ist generisch.

GitHub Actions, generisches Beispiel
name: codeqlon:  pull_request:  push:    branches: [main]  schedule:    - cron: "17 3 * * 1"      # wöchentlicher Volllauf jobs:  analyze:    runs-on: ubuntu-latest    permissions:      contents: read      security-events: write    strategy:      matrix:        language: [python, javascript-typescript]    steps:      - uses: actions/checkout@v7      - uses: github/codeql-action/init@v4        with:          languages: ${{ matrix.language }}          queries: security-extended      - uses: github/codeql-action/analyze@v4        with:          category: "/language:${{ matrix.language }}"

Drei Stellschrauben bestimmen das Ergebnis. Die Query-Suite legt fest, wie breit gesucht wird: Standard, security-extended oder security-and-quality. Die Kategorie je Sprache hält Ergebnisse getrennt. Der Trigger entscheidet, ob Funde vor dem Merge oder erst danach auffallen.

Wo KI in der Pipeline sitzt

Zwei Architekturen sind denkbar. Die folgende Gegenüberstellung ist ein Architekturbeispiel, keine Messung.

MerkmalHerstellerfunktion (Autofix)Eigene Triage-Stufe über SARIF
AufbauIn GitHub integriert, Auslösung am AlertSeparater Job liest SARIF, bewertet, schreibt Kommentar oder Label
ModellwahlVom Anbieter vorgegebenFrei, auch selbst betriebenes Modell möglich
CodeabflussCode geht an den Dienst des AnbietersHängt vom gewählten Modell und Betrieb ab
WartungBeim AnbieterPrompts, Schwellen und Auswertung liegen im eigenen Betrieb
KostenLizenz, bei Agentic Autofix zusätzlich AI Credits und Actions-MinutenModellbetrieb und Pipeline-Laufzeit

Grenzen

Lizenz

Die CodeQL-Bedingungen von GitHub erlauben die Analyse von Open-Source-Codebasen unter einer OSI-genehmigten Lizenz. Liegt ein solcher Code auf GitHub.com, ist auch die Datenbankerzeugung in CI und CD erlaubt. Für andere Codebasen, etwa private Repositories, gelten diese Rechte nicht. Dort greift eine kostenpflichtige Lizenz für GitHub Code Security oder GitHub Advanced Security.

Welche Lizenz die Nutzung voraussetztEntscheidungsbaum zur Lizenz. Frage: Open-Source-Codebasis mit OSI-genehmigter Lizenz? Ja: Nutzung nach CodeQL-Terms, bei Hosting auf GitHub.com auch in CI. Nein: Lizenz GitHub Code Security oder Advanced Security nötig. Für Agentic Autofix zusätzlich Copilot-Lizenz mit Cloud Agent, AI Credits und Actions-Minuten.Open-Source-Codebasis?OSI-genehmigte LizenzjaneinNutzung nach CodeQL-Termsbei GitHub.com-Hosting auch in CILizenz nötigGitHub Code Security oderGitHub Advanced SecurityAgentic Autofix zusätzlichCopilot-Lizenz mit Cloud AgentAI Credits und Actions-Minuten
Abbildung 4. Welche Lizenz die Nutzung voraussetzt. Stand der Bedingungen: Oktober 2026. Ob die Bedingungen für Ihren Fall zutreffen, klärt Ihre Rechtsberatung.

Erkennungsgrenzen

UrsacheWirkungHilft ein LLM?
Fehlende Modelle für BibliothekenFalse NegativesTeilweise, durch abgeleitete Quellen und Senken (IRIS)
Fehlender Kontext im DatenflussFehlalarmeTeilweise, durch Triage mit Umgebungscode
Fehlende Autorisierung, LogikfehlerKaum als Quelle-Senke-Muster fassbarNicht belegt
Dynamisches Verhalten zur LaufzeitFlüsse nicht vollständig verfolgbarNicht belegt

Fehlalarme bleiben

Selbst im besten Ergebnis der IRIS-Studie liegt die False Discovery Rate bei 84,82 %. Die Mehrzahl der gemeldeten Funde war also weiterhin falsch. Der Gewinn liegt im Abstand zu CodeQL allein, nicht in einem fehlalarmfreien Ergebnis.

Risiken beim Einsatz von LLMs

  • Nichtdeterminismus: Dieselbe Eingabe kann zu unterschiedlichen Urteilen führen. Triage-Ergebnisse sind deshalb nur eingeschränkt reproduzierbar.
  • Manipulation über Code: Kommentare und Strings im analysierten Code gelangen in den Prompt. Ein Modell kann dadurch beeinflusst werden.
  • Codeabfluss: Bei Cloud-Modellen verlässt Code die eigene Umgebung. Die Vertragslage und die Datenschutzfragen klärt Ihre Datenschutz- und Rechtsberatung.
  • Fehlerhafte Fixes: Ein verschwundener Alert beweist nicht, dass das Verhalten erhalten blieb. Dafür braucht es Tests und Review.
  • Kostenmodell: Agentische Läufe verbrauchen Credits und Pipeline-Minuten. Die Kosten wachsen mit der Zahl der zugewiesenen Alerts.

Betrieb

Der Datenbankaufbau und die Laufzeit wachsen mit der Codebasis. Kompilierte Sprachen brauchen je nach Sprache und Build-Modus einen funktionierenden Build in der CI. Alerts brauchen einen Prozess: wer bewertet sie, wer schließt sie mit welcher Begründung, und wie lange darf ein Fund offen bleiben.

Einordnung

SAST bleibt eine Methode mit klaren Grenzen. LLMs verschieben diese Grenzen an zwei Stellen: bei fehlenden Spezifikationen und bei der Triage. Die Zahlen stammen überwiegend aus Benchmarks und von Herstellern. Wie gut die Kombination in einer bestimmten Codebasis arbeitet, zeigt erst ein Lauf auf diesem Code.

Quellen

Sicherheitsprüfung bei Seovantis

Sicherheitsprüfungen führt Seovantis durch, wenn sie in der technischen Leistungsbeschreibung vereinbart sind. Wie die Prüfung vor der Übergabe abläuft, steht auf der Seite Arbeitsweise.

Ein ähnliches Vorhaben?

Schildern Sie kurz Ihre Ausgangslage. Ich melde mich innerhalb eines Werktags.

Anfrage stellen