
Aufzeichnungen und Präsentationsmaterial zur Überprüfung der Out-of-Bounds-Schreibverwundbarkeit CVE-2026-14662 in der PostgreSQL-Volltextsuche (tsvector/tsquery), validiert durch parallelen Docker-Betrieb der Vorher-(18.4)- und Nachher-Version (18.6).
Dies ist ein Bericht über CVE-2026-14662, die in den Volltextsuch-Datentypen (tsvector / tsquery) von PostgreSQL gefunden wurde. Dabei wurden die Version vor dem Fix (18.4) und nach dem Fix (18.6) gleichzeitig in Docker ausgeführt und die Unterschiede im Verhalten tatsächlich beobachtet.
Dies wurde für Lernzwecke im Bereich Sicherheit zusammengestellt und enthält auch Präsentationsmaterial.
| Element | Inhalt |
|---|
| CVE | CVE-2026-14662 |
| Ziel | tsvector / tsquery von PostgreSQL |
| Typ | Unzureichende Speichergröße durch Integer-Wraparound und Out-of-Bounds-Schreiben |
| CVSS | 8.8 / 10.0 (High) |
| Veröffentlichungsdatum | 2026-08-13 |
| Behobene Versionen | 18.5, 17.11, 16.15, 15.19, 14.24 |
Die Kette der Schwachstellen sieht wie folgt aus.
CWE-190 (Integer-Overflow) → CWE-131 (Falsche Berechnung der Puffergröße) → CWE-787 (Out-of-Bounds-Schreiben)
=Grundursache =Endgültige Auswirkung
.
├── docs/
│ └── presentation.md Präsentationsmaterial (Erklärung der Schwachstelle + Erklärung der CWE)
└── docker/
├── README.md Anleitung zur Nutzung der Reproduktionsumgebung
├── docker-compose.yml
├── init/ Gemeinsames Initialisierungs-SQL für beide Versionen
├── test/ PoC und Demo-SQL
└── run.sh Start → PoC-Ausführung → Ergebnisanzeige
Wenn Docker und Docker Compose vorhanden sind, kann die Reproduktion mit Folgendem durchgeführt werden.
cd docker
./run.sh
Die Container für 18.4 und 18.6 werden gestartet, das gleiche Initialisierungs-SQL wird eingespielt und anschließend wird derselbe PoC auf beide angewendet, wobei die Ergebnisse nebeneinander angezeigt werden. Details finden Sie in docker/README.md.
| Test | PostgreSQL 18.4 (vor dem Fix) | PostgreSQL 18.6 (nach dem Fix) |
|---|---|---|
| Wiederholte Selbst-OR-Verknüpfung von tsquery | Bis zum 18. Mal erfolgreich ohne Fehler (endgültig 8.650.748 Bytes) | Beim 17. Mal ERROR: tsquery is too large |
| Wort-Array mit einer Gesamtlänge von 1.200.000 Bytes | Erfolgreich | ERROR: string is too long for tsvector (1200000 bytes, max 1048575 bytes) |
| Ein einzelnes Wort mit 3.000 Bytes | Erfolgreich | ERROR: word is too long (3000 bytes, max 2046 bytes) |
Vor dem Fix werden Daten, die das interne Darstellungslimit (MAXSTRPOS = 1.048.575, abgeleitet aus einem 20-Bit-Bitfeld) überschreiten, ohne einen einzigen Fehler akzeptiert.
Der Grund, warum 18.6 genau beim „17. Mal" stoppt, lässt sich rechnerisch erklären, und es wurde bestätigt, dass Theorie und Messwerte bytegenau übereinstimmen (Details im Präsentationsmaterial).
Für die Überprüfung der Unterschiede wurde ein Klon des offiziellen PostgreSQL-Repositorys verwendet, dieser ist jedoch aufgrund seiner Größe (jeweils 185 MB) nicht in diesem Repository enthalten. Falls benötigt, holen Sie ihn wie folgt.
git clone --branch REL_18_4 --depth 1 https://github.com/postgres/postgres.git postgres-18.4
git clone --branch REL_18_6 --depth 1 https://github.com/postgres/postgres.git postgres-18.6
Die Dateien, in denen der Fix vorgenommen wurde, sind die folgenden drei.
src/backend/utils/adt/tsquery_util.csrc/backend/utils/adt/tsvector.csrc/backend/utils/adt/tsvector_op.c