17 Min. Lesezeit
Kritisch
Von

Drupal CVE-2026-9082 als Parser-Differential-Klasse — was die SQLi-Welle vom 20./22. Mai TYPO3-Betreibern sagt

24. Mai 2026. Drupal hat am 20. Mai SA-CORE-2026-004 publiziert (CVE-2026-9082, Highly Critical 20/25) — eine unauthentifizierte SQL-Injection im Core-Login-Endpunkt, die nur auf PostgreSQL-Backends wirkt; CISA hat sie am 22. Mai in den KEV-Katalog aufgenommen mit Remediation-Due-Date 27. Mai, Searchlight Cyber meldet „thousands of attacks within 48 hours“ (Drupal SA-CORE-2026-004, CISA KEV).

Wir betreiben kein Drupal — aber die Lücke gehört in dieselbe Klasse wie der SymfonyRuntime-Patch-Bypass vom 20. Mai (CVE-2026-46626): ein Parser-Differential zwischen zwei Schichten, die scheinbar dasselbe parsen.

Dieser Post seziert die Ursache, sortiert sie als Pattern, und zieht den Audit-Reflex auf den TYPO3-/Doctrine-DBAL-Stack durch.

Aufsicht-Stillleben auf matt-dunkler Schieferflaeche: zwei bruenierte messingfarbene Petschafte nebeneinander, darunter zwei cremefarbene Probe-Karten mit fast identischen Abdrucken — an einer winzigen abweichenden Stelle des linken Abdrucks beginnt ein einzelner Tropfen Oxblood-Tinte sich in die Papierfaser zu ziehen, die einzige gesaettigte Farbe im Bild. Links Auditor-Hauptbuch, oben rechts Messing-Lupe im Negativraum.
AI-generated · gpt-image 2.0

TL;DR — die 90-Sekunden-Zusammenfassung

FrageAntwort
Betroffen?Drupal Core 8.9.0 – <10.4.10, 10.5.0 – <10.5.10, 10.6.0 – <10.6.9, 11.0.0 – <11.1.10, 11.2.0 – <11.2.12, 11.3.0 – <11.3.10nur auf PostgreSQL-Backend. MySQL-, MariaDB- und SQLite-Drupal-Installationen sind nicht betroffen. End-of-Life-Linien Drupal 8.9 und 9 haben Best-Effort-Patches.
Risiko?Unauthentifizierte SQL-Injection über den JSON-Login-Endpunkt /user/login?_format=json (per Default aktiv im Core-User-Modul). Kein Session, kein CSRF-Token, kein Auth-State erforderlich. Eskalation auf RCE über PostgreSQL-Funktionen (z. B. COPY FROM PROGRAM bei entsprechenden DB-Rechten, oder Plattform-spezifische Privilege-Escalation). Aktive Ausnutzung in the wild seit 22. Mai 2026, PoC-Exploit publiziert.
Sofortmaßnahme?Drupal-Core auf 11.3.10 / 11.2.12 / 11.1.10 / 10.6.9 / 10.5.10 / 10.4.10 patchen — composer update drupal/core-recommended. Falls Patch im aktuellen Fenster nicht möglich: JSON-Format-Endpunkte am Reverse-Proxy blockieren (?_format=json auf /user/login abweisen) oder JSON-API-Modul temporär deaktivieren. Logs auf POST-Bodies an /user/login mit objektförmigem name-Feld sichten. Wir nutzen Drupal nicht — der Sofortmaßnahmen-Pfad gilt für Drittparteien, die Drupal-PostgreSQL-Setups betreiben.
Empfehlung?Drupal-Betreiber: in den nächsten 24 Stunden patchen — CISA-KEV-Due-Date ist der 27. Mai 2026. TYPO3-Betreiber: dieser Post ist kein Patch-Auftrag, sondern ein Audit-Auslöser. Drittanbieter-Extensions im eigenen TYPO3-Tree auf User-Pfade prüfen, die assoziativ-strukturierte JSON-Eingaben in QueryBuilder-->where()-Aufrufe oder dynamisch komponierte expr()->in(…)-Bedingungen weitergeben.
Kritikalität?Siehe Hero-Badge — critical. Aktive In-the-Wild-Ausnutzung, CISA-KEV-Listung in 48 Stunden, PoC-Exploit publiziert, unauthentifiziert über einen per Default aktiven Endpunkt. Für Drupal-PostgreSQL-Setups ist das die Sorte CVE, die das Wartungsfenster nicht mehr abwartet.

Was ist das Problem? — drei unabhängige Designentscheidungen, die übereinander zusammenbrechen

Die Lücke entsteht nicht an einer Stelle. Sie entsteht im Zusammenspiel von drei Designentscheidungen, die für sich genommen jede sinnvoll ist und in jedem Drupal-Code-Review bestanden hätte. Erst die Überlagerung in derselben Anfrage ergibt den unauthentifizierten DB-Zugriff.

Erster Beitrag — Symfony-JsonEncoder gibt assoziative Arrays heraus

Der JSON-Login-Endpunkt /user/login?_format=json ist Teil des Drupal-Core-User-Moduls und in jeder Installation per Default aktiv. Er parst den Request-Body über Symfonys JsonEncoder. Der Encoder dekodiert JSON-Objekte korrekt in assoziative PHP-Arrays — das ist nicht der Bug, sondern die dokumentierte Soll-Funktion. Wer das name-Feld als JSON-String schickt ({"name": "alice"}), bekommt im Controller einen String. Wer es als JSON-Objekt schickt ({"name": {"x": "1"}}), bekommt ein assoziatives Array. Der Drupal-Login-Controller reicht das, was er bekommt, ohne Form-Typ-Validierung an die Entity-Query weiter — weil Drupals Entity-Query Arrays als Mehrwert-Bedingung (IN (…)-Clause) interpretieren kann und damit ein legitimer Übergabe-Typ ist. Aus Controller-Sicht ist name polymorph: String oder Array, beides ist erlaubt.

Zweiter Beitrag — die implizite Trust-Annahme im DB-Abstraction-Layer

Drupals DB-API arbeitet mit benannten Placeholdern (:name) und einem Auto-Expand-Mechanismus für Array-Bedingungen (:name[]:name_0, :name_1, :name_2, …). Die Expand-Logik iteriert über das Array, baut für jeden Wert einen sauber-parametrisierten Placeholder — und konstruiert dabei den Placeholder-Namen aus dem Array-Key. Für numerisch-indexierte Arrays ([0 => 'a', 1 => 'b']) sind die Keys 0, 1, …, die Placeholder lesen :name_0, :name_1, …, alles wandert sauber durch PDO.

An dieser Stelle sitzt die unausgesprochene Annahme der Drupal-Core-Autoren: Werte sind untrusted, Keys sind trusted, weil Keys aus Sicht des Frameworks immer maschinen-erzeugte Indexe sind. Diese Annahme hält für jede interne Call-Site des DB-Layers; sie hält nicht, sobald ein User-Pfad eine assoziative Array-Form bis zur Placeholder-Konstruktion durchreicht. Das ist die eigentliche Schwachstelle — nicht ein vergessener Escape, nicht ein fehlender Cast, sondern eine Annahme über die Shape der Daten, die nirgends im Code als Constraint reifiziert war.

Dritter Beitrag — der PostgreSQL-spezifische Emissions-Pfad

Hier sitzt der Grund, warum die Lücke PG-only ist und nicht Drupal-weit. Drupals DB-API hat per-Backend-Driver-Overrides. Der pgsql-Driver hat eine eigene Placeholder-Emission, weil PostgreSQL bei Type-Cast-Hints, beim Umgang mit standard_conforming_strings und beim Mapping named-vs-positional anders tickt als MySQL und SQLite. Im PG-Driver erreichte der angreifer-kontrollierte Key einen Code-Pfad, in dem er roh in den SQL-String interpoliert wurde, bevor die PDO-Schicht die Werte parametrisierte. Auf MySQL und SQLite endete der äquivalente Pfad entweder mit einem Key-Drop oder mit einer Interpolation an einer SQL-Position, die den Placeholder-Kontext nicht verließ — und damit auch nicht zur SQLi wurde.

Drei Bedingungen, ein Bypass. Sie brauchen alle drei: einen Eingang, der dem Controller ein assoziatives Array übergibt (JSON-Endpunkt mit objektförmigem Feld); eine Abstraction-Layer-Annahme, dass die Keys trusted sind (universal in Drupal-Core); und einen Backend-Driver, der den Key in den SQL-String emittiert (nur PG). Sobald die drei zusammenkommen, hat ein anonymer Angreifer eine SQL-Injection auf einer Login-Route, die explizit für anonyme Anfragen gebaut wurde.

Der Patch und was er nicht repariert

Drupals Fix in 11.3.10 / 11.2.12 / 11.1.10 / 10.6.9 / 10.5.10 / 10.4.10 ist ein Einzeiler: array_values() auf das eingehende Bedingungs-Array. Damit werden die angreifer-kontrollierten Keys gestrippt und durch numerische Indexe ersetzt — die implizite Annahme des DB-Layers wird auf der Caller-Seite wiederhergestellt. Das ist ein defensibler 24-Stunden-Patch und er schließt die ausnutzbare Stelle vollständig.

Was er nicht repariert: die Annahme „Keys sind trusted“ lebt weiterhin im DB-Layer und ist nirgendwo im Drupal-Coding-Standard reifiziert. Die PG-vs.-MySQL-/SQLite-Divergenz im Placeholder-Emit-Pfad bleibt bestehen. Und die Frage, ob es weitere Call-Sites gibt, an denen ein User-Pfad eine assoziative Array-Shape bis zur Placeholder-Konstruktion durchreicht, ist mit dem Patch nicht beantwortet — nur an dieser einen Stelle pragmatisch unterbunden. Der Drupal-Security-Team-Reflex „erst patchen, dann härten“ ist nicht falsch in diesem Tempo; er hinterlässt aber eine Audit-Schuld in der Codebase, die sich Drupal als Open-Source-Projekt in den nächsten Monaten anschauen wird.

Wer ist betroffen?

BetroffenNicht betroffenBedingung
Drupal Core 8.9.0 – <10.4.10≥ 10.4.10+ PostgreSQL-Backend
Drupal Core 10.5.0 – <10.5.10≥ 10.5.10+ PostgreSQL-Backend
Drupal Core 10.6.0 – <10.6.9≥ 10.6.9+ PostgreSQL-Backend
Drupal Core 11.0.0 – <11.1.10≥ 11.1.10+ PostgreSQL-Backend
Drupal Core 11.2.0 – <11.2.12≥ 11.2.12+ PostgreSQL-Backend
Drupal Core 11.3.0 – <11.3.10≥ 11.3.10+ PostgreSQL-Backend
End-of-Life Drupal 8.9 / 9 (PostgreSQL-Backend)Best-Effort-Patches, kein Long-Term-Support
Drupal Core auf MySQL / MariaDB / SQLiteVom Backend-Driver-Override nicht erfasst — nicht ausnutzbar in der bekannten Pfad-Kombination

Außerhalb der direkten Drupal-Betroffenheit, aber stilistisch zur Klasse gehörig:

Auswirkungen

Wir sortieren nicht nach CVSS-Zahlen (Drupal hat den 20/25-Score über die eigene Risk-Skala vergeben, NVD läuft mit CVSS 6.5, die operative Schwere liegt deutlich darüber), sondern nach beobachteter Eskalations-Tiefe.

Eskalations-Tiefe 1 — Information Disclosure. Ein anonymer Angreifer kann über die SQLi beliebige Tabelleninhalte lesen: Benutzer-Hashes, Session-Tokens, Konfigurations-Werte, beliebige Custom-Entity-Daten. Bei Drupal-Plattformen, die personenbezogene Daten in Custom-Entities oder Feldern halten, ist das ein vollständiger Datenabfluss aus der DB-Schicht.

Eskalations-Tiefe 2 — Privilege Escalation. Über INSERT/UPDATE auf users_field_data und den Drupal-Permissions-Tabellen kann der Angreifer eigene Konten anlegen oder bestehende Konten mit privilegierten Rollen ausstatten. Sobald ein Admin-Konto kontrolliert wird, ist der Angriff aus der SQLi-Schicht in die Anwendungs-Schicht migriert.

Eskalations-Tiefe 3 — Remote Code Execution über PostgreSQL. PostgreSQL stellt mit COPY FROM PROGRAM einen direkten Aufruf von OS-Kommandos zur Verfügung, sofern der DB-User die nötigen Rechte hat (typisch bei selbstbetriebenen PG-Installationen, weniger typisch bei Managed-Services wie RDS, Aiven, Hetzner Managed PG). Dazu kommen über lo_import / lo_export File-System-Zugriffe und über CREATE EXTENSION ggf. weitere RCE-Pfade. Searchlight Cyber demonstriert in der publizierten Analyse einen End-to-End-Pfad bis zur OS-Shell. Akamai bestätigt aktive Exploit-Versuche mit RCE-Payload in der eigenen Telemetrie.

Eskalations-Tiefe 4 — Lateral Movement in der Cloud. Sobald die OS-Schicht erreicht ist, hängen IAM-Rollen, Cloud-Metadata-Endpunkte und potenziell SSM/Cloud-Init-Pfade in derselben Trust-Zone. Wer eine Drupal-Installation auf einer EC2-Instance betreibt, deren IAM-Rolle Zugriff auf S3-Buckets oder Secrets Manager hat, verliert in dem Moment, in dem die SQLi zur RCE eskaliert, auch die Cloud-Credentials.

Die Klammer um alle vier: die operative Schwere wird nicht durch die SQLi selbst gesetzt, sondern durch das, was unter der DB-Schicht hängt. Eine Hetzner-Managed-PG-Installation hinter einer Drupal-Instance mit moderaten DB-User-Rechten endet vermutlich bei Tiefe 2. Eine selbstbetriebene PG-Instance auf einem EC2-Host mit weiten IAM-Rollen endet bei Tiefe 4. Der CVSS-6.5-Wert ist eine durchschnittliche Modellierung; in der Praxis sitzt die Verteilung an beiden Rändern.

Mitigation / Sofortmaßnahmen

Wir machen den Sofortmaßnahmen-Block für Drupal-Betreiber kurz — der Patch ist trivial, die Empfehlung ist sofort. Der Schwerpunkt liegt im nächsten Abschnitt („Was wir konkret getan haben“).

Pfad 1 — Vollständiger Patch (empfohlen)

 

# Patch ziehen
composer update drupal/core-recommended drupal/core --with-all-dependencies

# Stand prüfen
composer show drupal/core
# Erwartet: 10.4.10 | 10.5.10 | 10.6.9 | 11.1.10 | 11.2.12 | 11.3.10 — passend zur Linie

# Datenbank-Updates ausspielen
drush updatedb
drush cache:rebuild

 

Wer Composer-Audits eingebaut hat, sieht den Block sofort. Wer das nicht hat, jetzt installieren:

 

composer require --dev roave/security-advisories:dev-latest

 

Pfad 2 — Stopgap, falls Patch im aktuellen Fenster nicht möglich

Vier Mitigationen auf Edge-Level, kumulativ — keine ersetzt den Patch:

1. JSON-Format am Login-Endpunkt blockieren. Den _format=json-Query-Parameter auf /user/login am Reverse-Proxy abweisen. nginx:

 

location = /user/login {
    if ($arg__format = "json") {
        return 403;
    }
    # ... übliche Drupal-Backend-Verkettung
}

 

Caddy:

 

@drupal_login_json {
    path /user/login
    query _format=json
}
respond @drupal_login_json 403

 

2. JSON-API-Modul temporär deaktivieren, falls es nicht produktiv genutzt wird:

 

drush pm:uninstall jsonapi

 

3. WAF-Regel auf POST-Bodies an /user/login mit objektförmigem name-Feld. Suricata-Rule-Skizze (nicht vollständig):

 

alert http any any -> $HTTP_SERVERS any (msg:"Drupal CVE-2026-9082 JSON name-object";
    http.uri; content:"/user/login"; http.method; content:"POST";
    http.request_body; content:"\"name\":{"; sid:2026908201;)

 

4. PostgreSQL-User-Rechte hart begrenzen. Wenn der Drupal-DB-User nicht zwingend pg_execute_server_program-Rolle oder Superuser-Privileg hat, ist die Eskalation auf RCE über COPY FROM PROGRAM verschlossen. Das ist ohnehin der Default für Managed-PG-Services, ist aber für selbstbetriebene PG-Installationen ein Audit-Schritt.

Pfad 3 — Detection: aktive Exploit-Versuche erkennen

 

# nginx-Access-Log nach JSON-Login-POSTs scannen
grep -E 'POST /user/login.*_format=json' /var/log/nginx/access.log \
  | awk '{print $1, $4, $7}' \
  | sort | uniq -c | sort -nr | head -20

# Drupal-Watchdog-Log nach DB-Fehlern an der EntityQuery sichten
drush watchdog:show --type=database --severity=error --count=200

# PostgreSQL-Slow-Query-Log nach ungewöhnlichen Bedingungs-Strukturen
grep -E "FROM users_field_data WHERE.*name" /var/log/postgresql/postgresql-*.log \
  | head -50

 

Wer Falco / Tetragon / eBPF-Monitoring fährt, sieht zusätzlich, ob aus dem PHP-FPM-Prozess heraus ungewöhnliche Outbound-Verbindungen oder Shell-Exec-Pfade entstehen — die Eskalations-Tiefe-3-Spur.

Detection / Prüfung

Dieser Abschnitt ist im klassischen CVE-Template eigenständig vorgesehen (Element 9 nach Sektion 3 des Redaktionsleitfadens). Wir falten ihn hier mit dem „Pfad 3“-Block oben zusammen — die Detection-Hinweise sitzen dort technisch sauberer im Kontext der Mitigation. Der explizite Detection-Block für Plattform-Betreiber:

Composer-Stand und Audit:

 

composer audit --format=json | jq '.advisories[] | select(.package == "drupal/core")'

 

Watchdog-Auswertung über Drush:

 

drush watchdog:show --type=user --severity=warning --count=500 \
  | grep -iE 'login|json|format'

 

Pre-Patch-Forensik: Wer die Plattform vor dem Patch publiziert betrieben hat und keine WAF dazwischen lag, scannt die Access-Logs der letzten zwei Wochen rückwirkend nach POSTs auf /user/login?_format=json und sichert die Anfragen-Bodies, sofern das Log-Format sie enthält. Bei Treffern: vollständige Inventur der DB-Rechte des Drupal-DB-Users, Inventur aller Admin-Accounts auf neue Einträge, Inventur der Module auf nachträglich installierte Extensions.

Betreiberempfehlung

Operational Decision Block

Vor den Sub-Szenarien die Wenn/Dann-Lese-Reihenfolge:

Mittelstand

Für die wenigen Drupal-PostgreSQL-Setups im DACH-Mittelstand: 24 Stunden ist das operative Fenster, nicht das Wartungsfenster. Wer Composer-Updates monatlich fährt, hat in dieser Welle einen Anlass, auf zweiwöchig zu ziehen — die Glasswing-Wellen werden nicht weniger.

Enterprise

Gleicher Patch-Pfad, plus eine Inventur der DB-User-Rechte. Falls der Drupal-DB-User mehr Privilegien hat, als für den Betrieb tatsächlich nötig sind (typisch: Superuser-Default aus dem Initial-Setup, nie zurückgenommen), ist die Eskalations-Tiefe 3 (RCE über PostgreSQL) operativ offen. Least-Privilege-Härtung der DB-User-Rechte ist die strukturelle Konsequenz aus dieser CVE — unabhängig davon, ob der konkrete Patch sitzt.

Kubernetes / Container-Plattformen

Drupal-Images neu bauen, sobald der Composer-Update in den Build-Layer eingespielt ist. Wer Wolfi-OS- / Chainguard-PHP-Images fährt, sieht den Patch im Base-Image nicht — der sitzt im App-Layer (Composer-Tree). Multi-Stage-Build neu auslösen, neuen Image-Tag pushen, Pods rollend austauschen. Container-Restart ist Pflicht, weil Drupal die Container-Reuse-Optimierungen (z. B. OPCache, Twig-Compiled-Cache) sonst mit der alten Code-Basis weiterfährt.

Deklarative Stacks (NixOS / Talos / Flatcar)

nixpkgs-Pin auf den Drupal-Patch-Tag ziehen oder den composer update im build-Layer fixieren. Talos und Flatcar: Patches sitzen im App-Image, nicht im OS-Layer; der Roll-Out folgt der App-Update-Pipeline, nicht dem OS-Update-Window.

Was wir konkret getan haben

Wir betreiben kein Drupal in produktiven Kundenplattformen — also kein Patch-Zug bei uns für diese CVE. Was wir gemacht haben, betrifft die eigene Codebase und die Drittanbieter-Extensions in den TYPO3-Trees, die wir betreuen.

Der eigentliche Audit-Reflex sitzt im Übertrag auf den TYPO3-/Doctrine-DBAL-Stack. TYPO3 nutzt Doctrine DBAL statt einer eigenen DB-API. Doctrine hat kein Auto-Expand auf Arrays — wer eine IN-Bedingung will, muss Connection::executeQuery() mit einem expliziten Value-Array aufrufen und entweder die Placeholder selbst aufzählen oder den Connection::PARAM_*_ARRAY-Typ-Hint setzen. Damit ist die exakte Drupal-Lücke nicht portabel. Das Pattern aber sehr wohl: jede TYPO3-Extension, die User-Input via $request->getParsedBody() oder $request->getQueryParams() entgegennimmt und ohne explizite Form-Validierung an einen QueryBuilder->where(…)-Aufruf weiterreicht, kann an einer assoziativ-strukturierten Eingabe stolpern — vor allem, wenn die Where-Bedingung über $queryBuilder->expr()->in(…) mit dynamisch komponiertem Spalten-String aufgebaut wird oder wenn createNamedParameter() ohne expliziten Typ-Hint aufgerufen wird.

Wir haben am Wochenende einen grep-Sweep über die Drittanbieter-Extension-Trees unserer Kundenplattformen gefahren:

 

# In jedem TYPO3-Projekt-Tree
find typo3conf/ext -type f -name "*.php" -exec grep -lE \
  'getParsedBody|getQueryParams' {} \; \
  | xargs -I {} grep -lE 'QueryBuilder|createNamedParameter|expr\(\)->in' {} \
  | sort -u

 

Die Treffer-Liste ist überschaubar, weil die meisten Extensions strenge Form-Validierung über Extbase/Fluid oder TYPO3 Forms machen. Drei Extensions im Long-Tail-Bereich (alle Custom-Builds aus den Jahren vor 2024, also vor der breiten Migration auf Extbase 14) haben wir manuell durchgesehen — keine ausnutzbare Stelle gefunden, aber zwei der drei Extensions hatten Code-Pfade, die ein expliziter Typ-Hint im createNamedParameter() sauberer gemacht hätte. Die haben wir aufgenommen in das nächste Refactoring-Fenster, ohne Eskalation.

Reflexion in zwei Punkten. Erstens: dass wir keine Drupal-Plattform betreiben, ist keine Glanzleistung — es ist eine Plattform-Wahl, die wir vor Jahren getroffen haben und die in solchen Wellen punktuell weniger Arbeit macht. In anderen Wellen (etwa beim Symfony-20.05.-Patch-Tuesday) waren wir voll in der Pflicht. Die Plattform-Wahl ist eine Risiko-Verteilung, kein Risiko-Ausschluss. Zweitens: Parser-Differentials wie diese CVE-Klasse sind nicht durch Codebase-Größe oder Code-Review-Kultur eines einzelnen Projekts beherrschbar — sie sitzen an Schichten-Übergängen, wo zwei Komponenten denselben Input minimal anders interpretieren. Drupal-Symfony-JsonEncoder ↔ Drupal-DB-Layer ist die eine Klasse; SymfonyRuntime-parse_str ↔ SAPI-argv-Builder ist die andere; HtmlSanitizer-URL-Parser ↔ Browser-URL-Parser ist die dritte. Wer diese Klasse strukturell aus dem eigenen Stack drücken will, baut keine bessere Sanitizing-Funktion, sondern reduziert die Anzahl der Übergänge: weniger Parser-Stufen, weniger Format-Indirektionen, weniger Auto-Magic in Abstraktion-Layern.

Häufige Fragen zur Drupal-SQLi vom 20./22. Mai 2026

Sind TYPO3-Plattformen mit MariaDB-Backend von CVE-2026-9082 indirekt betroffen?+

Nein. Die Lücke sitzt im Drupal-Core, nicht im TYPO3-Core; sie braucht zusätzlich PostgreSQL als Backend. TYPO3 auf MariaDB ist von dieser CVE in keiner Form berührt. Die Audit-Lehre (Drittanbieter-Extensions auf User-strukturierte Array-Eingaben in DB-Bedingungen prüfen) gilt aber unabhängig vom DB-Backend.

Wir betreiben eine TYPO3-Plattform auf PostgreSQL. Müssen wir jetzt etwas zusätzliches tun?+

Die Drupal-CVE selbst trifft Sie nicht. PostgreSQL als TYPO3-Backend ist seit TYPO3 v11 stabil unterstützt und wir empfehlen es in bestimmten Setups aktiv (Multi-Master-Replikation, JSONB-Heavy-Workloads). Was Sie tun: einmal die DB-User-Rechte für den TYPO3-DB-User auf Least-Privilege prüfen — kein pg_execute_server_program, kein Superuser, keine CREATE EXTENSION-Rechte. Das ist Standard-Härtung, unabhängig von dieser CVE, aber die Welle ist ein guter Anlass.

Wie prüfe ich, ob meine Drittanbieter-TYPO3-Extensions User-Pfade in DB-Bedingungen durchreichen?+

Der grep-Sweep aus dem „Was wir getan haben“-Block ist ein erster Filter. Strenger: pro Extension, die in der Treffer-Liste landet, die Controller-Action-Methoden manuell durchsehen — wo wird getParsedBody() oder getQueryParams() aufgerufen, was passiert mit dem Resultat, läuft es ohne instanceof string-Check oder ohne Extbase-Form-Validierung in einen QueryBuilder-Aufruf? Wenn ja: ein createNamedParameter($value, Connection::PARAM_STR)-Typ-Hint ist die einfachste Mitigation. Strenger: die Action-Method-Signatur mit einem Symfony-Validator-Constraint oder einem Extbase-DTO ausstatten und den Input vor dem QueryBuilder validieren.

Drupal hat den 20/25-Risk-Score vergeben, NVD nennt CVSS 6.5 — was stimmt jetzt?+

Beide. Die Drupal-Risk-Skala („Highly Critical 20/25“) gewichtet stärker nach Exploitability und Privilegien-Anforderung; NVDs CVSS-3.1-Modellierung sitzt strenger im Standard und kommt mit 6.5 raus (vor allem, weil RCE-Eskalation Setup-abhängig ist). Operativ relevant ist der CISA-KEV-Eintrag: aktive Ausnutzung in the wild ist das stärkste externe Signal, dass der CVSS-Wert die tatsächliche Schwere unterzeichnet. Wer auf den NVD-Score wartet, bevor er patcht, kommt zu spät.

Was ist das Parser-Differential-Pattern und warum betont der Post das so?+

Ein Parser-Differential ist eine Schwachstelle-Klasse, in der zwei Software-Komponenten denselben Input scheinbar gleich, in Wahrheit aber an einer Edge-Case-Stelle minimal unterschiedlich interpretieren — und ein Angreifer sitzt auf der Übersetzungs-Stelle. Drupal-Symfony-JsonEncoder gibt assoziative Arrays heraus, Drupal-DB-Layer geht von Index-Arrays aus — die Übersetzungs-Stelle ist die Lücke. SymfonyRuntime parse_str und SAPI-argv-Builder bauen denselben Query-String unterschiedlich auf — die Übersetzungs-Stelle war CVE-2026-46626. HtmlSanitizer-URL-Parser und Browser-URL-Parser akzeptieren minimal unterschiedliche URL-Formate — die Übersetzungs-Stelle war CVE-2026-45064/45066. Wer das Pattern als Klasse benennt, hat einen Audit-Reflex, der über die einzelne CVE hinaus trägt.

Reicht ein WAF-Patch (Cloudflare, Akamai, Imperva) für die nächsten Tage, bis wir patchen können?+

Als Stopgap ja, als Ersatz nein. Alle drei großen WAF-Anbieter haben innerhalb von 24 Stunden eine Regel ausgerollt, die POST-Bodies an /user/login?_format=json mit objektförmigem name-Feld blockiert. Das schließt den bekannten Exploit-Pfad. Was es nicht schließt: alternative JSON-Endpunkte im Drupal-Tree, die das gleiche Pattern triggern könnten, und benutzerdefinierte Module mit eigenen JSON-Routen, die ebenfalls assoziative Arrays an Entity-Queries weiterreichen. Patch bleibt Pflicht, WAF kauft Ihnen die Zeit für den Roll-Out.

Fazit

CVE-2026-9082 ist für Moselwal nicht der Patch-Auslöser, sondern der Audit-Auslöser. Wir betreiben kein Drupal, aber wir betreiben TYPO3 — und die Klasse, der die Drupal-Lücke angehört, ist nicht Drupal-spezifisch. Drei unabhängige Designentscheidungen, die für sich genommen sinnvoll sind, ergeben übereinander den unauthentifizierten DB-Zugriff: ein JSON-Encoder, der assoziative Arrays korrekt dekodiert; ein DB-Layer, der die Array-Keys implizit als trusted annimmt; ein Backend-Driver, der den Key in den SQL-String emittiert. Dasselbe Pattern haben wir am 20. Mai bei SymfonyRuntime (CVE-2026-46626, parse_str vs. SAPI-argv) und in der Symfony-HtmlSanitizer-Welle (CVE-2026-45064/-45066, URL-Parser-Differentials) gesehen — drei verschiedene Stacks, dieselbe Klasse, drei Wochen Zeitfenster. Die strukturelle Konsequenz ist nicht „bessere Sanitizing-Funktionen“, sondern weniger Übergänge zwischen Parser-Stufen, weniger Auto-Magic in Abstraktions-Layern, mehr explizite Typ-Hints an den Schichten-Übergängen. Die Frage lautet nicht, ob die nächste Parser-Differential-CVE in Ihrem Stack kommt. Sie lautet, an welcher Schichten-Übergang Sie sie als Erstes sehen werden — und ob Sie dort genau hingeschaut haben, bevor sie kommt.

Bevor die nächste Parser-Differential-CVE kommt — sprechen wir über Ihren Extension-Tree.

Wir auditen Ihren TYPO3-/Doctrine-DBAL-Stack auf Parser-Differential-Pattern, bevor die nächste CVE-Welle kommt.

Konkret: grep-Sweep über Drittanbieter-Extension-Trees, manuelle Code-Review der Treffer-Liste auf Controller-Action-Methoden mit User-strukturierten Eingaben in QueryBuilder-Bedingungen, Mitigations-Patches mit expliziten Typ-Hints in createNamedParameter(), optional Extbase-DTO-Härtung mit Validator-Constraints. Wir liefern Ihnen die Treffer-Liste, den Patch-Vorschlag und die Test-Suite-Ergänzung als zusammenhängenden Audit-Lieferschein.

Plattformbetrieb statt Beratung-on-paper. Wer den Audit-Reflex dauerhaft in die CI-Pipeline ziehen will, kommt mit uns zum DevSecOps-Service mit composer audit-Gate, Static-Analysis (Psalm/PHPStan auf Security-Level) und QueryBuilder-spezifischen Custom-Rules — siehe /devsecops.html und /services.html.

Termin direkt vereinbaren

Über den Autor

Foto von Kai Ole Hartwig.

Kai Ole Hartwig

Founder · Moselwal Digitalagentur · OnlyOle

Programmiert seit 2002 – autodidaktisch gelernt, 2012 mit KO-Web selbständig gemacht, heute Moselwal. Über 100 Projekte, Fokus auf Security, Performance, Automatisierung und Qualität.