
Vulnerabilità di scrittura fuori dai limiti trovata nella ricerca full-text di PostgreSQL (tsvector/tsquery) CVE-2026-14662: registrazione della verifica eseguita eseguendo in parallelo con Docker la versione non corretta (18.4) e quella corretta (18.6), insieme ai materiali di presentazione
Questo è il resoconto di come ho eseguito simultaneamente in Docker la versione precedente alla correzione (18.4) e quella successiva (18.6) di PostgreSQL per osservare concretamente la differenza di comportamento riguardo alla CVE-2026-14662, una vulnerabilità trovata nei tipi di dati per la ricerca full-text (tsvector / tsquery).
Il materiale è stato preparato a scopo di apprendimento sulla sicurezza e include anche le slide della presentazione.
| Voce | Contenuto |
|---|
| CVE | CVE-2026-14662 |
| Oggetto | tsvector / tsquery di PostgreSQL |
| Tipo | Dimensione di allocazione insufficiente e scrittura fuori dai limiti dovute a integer wraparound |
| CVSS | 8.8 / 10.0 (High) |
| Data di pubblicazione | 2026-08-13 |
| Versioni corrette | 18.5, 17.11, 16.15, 15.19, 14.24 |
La catena delle debolezze è la seguente.
CWE-190 (Integer Overflow) → CWE-131 (Calcolo errato della dimensione del buffer) → CWE-787 (Scrittura fuori dai limiti)
=Causa principale =Impatto finale
.
├── docs/
│ └── presentation.md Slide della presentazione (spiegazione della vulnerabilità + spiegazione delle CWE)
└── docker/
├── README.md Istruzioni per l'ambiente di riproduzione
├── docker-compose.yml
├── init/ SQL di inizializzazione comune eseguito su entrambe le versioni
├── test/ PoC e SQL per la demo
└── run.sh Avvio → esecuzione del PoC → visualizzazione dei risultati
Se hai Docker e Docker Compose, puoi riprodurre il tutto con il solo comando seguente.
cd docker
./run.sh
Verranno avviati i container di 18.4 e 18.6, verrà caricato lo stesso SQL di inizializzazione su entrambi e lo stesso PoC verrà eseguito su entrambi, mostrando i risultati affiancati. Per i dettagli, consulta docker/README.md.
| Test | PostgreSQL 18.4 (pre-correzione) | PostgreSQL 18.6 (post-correzione) |
|---|---|---|
| Ripetizione dell'auto-OR di tsquery | Successo senza errori fino a 18 volte (finale: 8.650.748 byte) | ERROR: tsquery is too large alla 17ª iterazione |
| Array di parole con lunghezza totale di 1.200.000 byte | Ha successo | ERROR: string is too long for tsvector (1200000 bytes, max 1048575 bytes) |
| Una singola parola di 3.000 byte | Ha successo | ERROR: word is too long (3000 bytes, max 2046 bytes) |
Nella versione pre-correzione, i dati che superano il limite della rappresentazione interna (MAXSTRPOS = 1.048.575, derivante dal campo di bit a 20 bit) vengono accettati senza generare alcun errore.
Il motivo per cui 18.6 si ferma "esattamente alla 17ª iterazione" è spiegabile con un calcolo, e ho confermato che il valore teorico e quello misurato coincidono byte per byte (dettagli nelle slide della presentazione).
Per verificare le differenze ho usato un clone del repository ufficiale di PostgreSQL, ma non è incluso in questo repository perché è molto grande (185MB ciascuno). Se necessario, puoi ottenerlo come segue.
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
I file che sono stati corretti sono i seguenti tre.
src/backend/utils/adt/tsquery_util.csrc/backend/utils/adt/tsvector.csrc/backend/utils/adt/tsvector_op.c