Aggiornare PostgreSQL: le 52 falle chiuse il 12 novembre
PostgreSQL 18.7 e le altre minor chiudono 52 vulnerabilità, due sulla row level security. Le query per controllare versione, permessi e tabelle esposte.

Indice dei contenuti
Il 12 novembre il gruppo che sviluppa PostgreSQL ha pubblicato le versioni 18.7, 17.12, 16.16, 15.20 e 14.25. Non è la solita minor con qualche bug sistemato: l’annuncio ufficiale parla di 52 vulnerabilità di sicurezza chiuse in un colpo, più di 140 bug. Qui sotto ci sono tre query da lanciare su ciascun database: le ho provate su un PostgreSQL 16.15, cioè proprio una versione ancora da aggiornare.
Aggiornare PostgreSQL a una minor è in genere un lavoro da dieci minuti. Questa volta ci sono passaggi in più dopo il riavvio, e la 14 non riceve più patch.
Cosa è uscito il 12 novembre
L’elenco delle CVE (il codice pubblico che identifica ogni vulnerabilità) è lungo, e molte voci hanno lo stesso finale: “executes arbitrary code”. Il punteggio CVSS, la scala da 0 a 10 che misura la gravità, arriva a 8.8 per decine di voci. Le aree toccate sono diverse: conversioni di tipo, plperl e pltcl, pg_dump e pg_restore, dblink, la replica logica.
Nello stesso annuncio c’è scritto che la 14.25 è l’ultima release di PostgreSQL 14, ora fuori supporto e senza più correzioni, nemmeno di sicurezza. Il rilascio generale di PostgreSQL 19 è invece previsto per il 19 novembre 2026.
Una falla che secondo chi l’ha studiata ha 22 anni
La voce più raccontata è la CVE-2026-6460. La scheda ufficiale dice che una confusione di tipo permette a chi crea oggetti nel database di eseguire codice arbitrario come l’utente del sistema operativo che fa girare PostgreSQL. La strada principale è ALTER ... SET DATA TYPE, cioè cambiare il tipo di una colonna o di un campo, ma la scheda cita anche altri percorsi DDL (i comandi che creano e modificano la struttura: tabelle, tipi, colonne).
Il ricercatore Mehmet Ince ha raccontato come ci è arrivato in un post del 9 novembre, parte di una serie sui rischi sistemici del Postgres gestito. Secondo lui è una zero-day rimasta nel cuore di PostgreSQL per 22 anni. Lui stesso precisa che non è una scoperta solo sua: PostgreSQL l’ha trattata come una CVE ombrello per un’intera famiglia di problemi sui tipi composti, segnalati da più ricercatori. Nel post scrive anche di aver studiato gli interni di Postgres facendosi fare da insegnante da un agente AI.
Il dettaglio che conta per chi gestisce un database sta nel vettore CVSS: PR:L, privilegi bassi. Non serve essere superutente. Basta un ruolo che possa creare oggetti, e da lì si arriva a comandi eseguiti sulla macchina del database. E creare un oggetto è più facile di quanto sembri, come si vede due query più sotto.
Che versione di PostgreSQL stai usando
La prima query confronta la versione del server con la minima corretta per la sua major. server_version_num restituisce un intero: 160015 significa 16.15.
SELECT current_setting('server_version_num')::int AS versione,
CASE current_setting('server_version_num')::int / 10000
WHEN 18 THEN 180007
WHEN 17 THEN 170012
WHEN 16 THEN 160016
WHEN 15 THEN 150020
WHEN 14 THEN 140025
END AS minima_corretta;
Sul mio server di prova esce 160015 | 160016: da aggiornare. Se minima_corretta è vuota, la major è fuori dall’elenco: o più vecchia della 14, e allora non riceve correzioni da tempo, o è la 19 in prova.
Sul mio Ubuntu il pacchetto si chiama 16.15-0ubuntu0.24.04.1 e la query restituisce 16.15: il numero corrisponde. Se invece usi un pacchetto che applica le correzioni senza cambiare versione, come succede per PHP su alcune distribuzioni (ne ho scritto in come capire se il tuo PHP ha davvero la patch), la conferma sta nel changelog del pacchetto.
Chi può creare oggetti nel tuo database
Visto che la CVE-2026-6460 parte da chi crea oggetti, viene da chiedersi chi può farlo. La risposta onesta è: quasi chiunque si connetta. Fino alla versione 14 chiunque poteva creare tabelle nello schema public per impostazione predefinita. La 15 ha tolto quel permesso, ma le note di rilascio della 15 avvertono che aggiornare un cluster o ripristinare un dump conserva i permessi esistenti su public. Un database nato su una versione vecchia e migrato negli anni può averli ancora.
SELECT has_schema_privilege('public', 'public', 'CREATE')
AS chiunque_crea_in_public;
Il primo public è lo pseudo-ruolo che comprende tutti, il secondo è lo schema. Se esce t, qualsiasi utente che si connette può creare oggetti lì, e il permesso si toglie con REVOKE CREATE ON SCHEMA public FROM PUBLIC; dopo aver controllato che nessuna migrazione ne abbia bisogno.
Un f però non ti mette al riparo. Ho creato un ruolo nuovo, senza nessun permesso su public, e ho lanciato CREATE TYPE pg_temp.prova AS (a int);: il tipo è stato creato nello schema temporaneo della sessione, che per impostazione predefinita è aperto a tutti. Questa query è igiene dei permessi, non una difesa dalla CVE-2026-6460. Contro quella serve l’aggiornamento, e conviene trattare ogni ruolo che si connette come capace di creare oggetti.
Le due falle che aggirano la row level security
Qui il discorso tocca le web app che scrivo io. La row level security (RLS) è il meccanismo di Postgres che decide riga per riga chi vede cosa: in un gestionale fa in modo che ogni cliente legga solo i propri ordini anche se la tabella è una sola. Su GitWatchman e CycleTour, due progetti miei su Supabase, l’accesso ai dati passa da queste regole, come ho spiegato nell’articolo sull’area riservata clienti.
Nel pacchetto del 12 novembre ci sono due voci che la riguardano direttamente:
- CVE-2026-120154, punteggio 4.3: un utente con i permessi INSERT, UPDATE e SELECT su una tabella può leggere tutte le righe nonostante le regole RLS, ripetendo un
INSERT ... ON CONFLICT DO UPDATE. La scheda precisa che non permette scritture improprie. - CVE-2026-116311, punteggio 5.4: con
DROP OWNEDun ruolo può togliersi dalle policy restrittive e leggere o modificare righe che quelle policy dovevano negargli.
La prima mi interessa di più. INSERT ... ON CONFLICT DO UPDATE è quello che si chiama upsert: inserisci una riga, e se esiste già la aggiorni. Supabase lo espone anche dal client JavaScript con il metodo .upsert(). Non so dire se la falla sia sfruttabile attraverso l’API di Supabase: la scheda ufficiale non ne parla e non ho trovato un’analisi che lo dimostri. So però quali tabelle hanno la combinazione di permessi descritta, e quella si controlla:
SELECT c.oid::regclass AS tabella, r.rolname AS ruolo
FROM pg_class c
CROSS JOIN pg_roles r
WHERE c.relkind IN ('r', 'p')
AND c.relrowsecurity
AND r.rolname NOT LIKE 'pg\_%'
AND NOT r.rolsuper
AND NOT r.rolbypassrls
AND has_table_privilege(r.oid, c.oid, 'SELECT')
AND has_table_privilege(r.oid, c.oid, 'INSERT')
AND has_table_privilege(r.oid, c.oid, 'UPDATE');
La query elenca le tabelle con RLS attiva (anche partizionate) e i ruoli che hanno tutti e tre i permessi, esclusi superutenti e ruoli con l’attributo BYPASSRLS, che le regole le saltano comunque. Un caso la query non lo distingue: il proprietario della tabella salta la RLS se non hai attivato FORCE ROW LEVEL SECURITY, quindi se nell’elenco compare il proprietario va letto con questo in mente. Nel mio test ho creato una tabella note con RLS e un ruolo authenticated con SELECT, INSERT e UPDATE: la query la trova. Se nell’elenco compare un ruolo usato da utenti che si registrano da soli, quella tabella è il motivo per non rimandare l’aggiornamento.
Aggiornare: binari, riavvio e i passaggi dopo
Le release minor sono cumulative e non richiedono dump, restore o pg_upgrade: secondo l’annuncio basta fermare PostgreSQL e aggiornarne i binari. Il riavvio c’è comunque, quindi va messo in un momento in cui l’app può restare ferma qualche minuto.
Questa volta l’annuncio elenca anche lavori da fare dopo, legati a bug corretti nella stessa release. I principali:
- Se sospetti che un indice GIN sia danneggiato, ricostruiscilo con
REINDEX INDEX. - Se usi l’estensione pg_trgm, ricostruisci gli indici GiST con l’operator class
gist_trgm_ops. - Gli indici B-tree su colonne
bpcharsenza lunghezza vanno ricostruiti; le colonnechar(n)non sono toccate. - Se leggendo una tabella compare l’errore “missing chunk number”, lancia
REINDEX TABLEsu quella tabella. - Con le tabelle partizionate, l’annuncio dà una query per trovare i vincoli
NOT NULL NO INHERITda togliere o riparare. - Con i backup incrementali, fai un nuovo backup completo e usalo come base per i successivi.
Chi ha saltato una o più minor precedenti deve leggere anche le loro note, perché i passaggi si sommano.
Su un servizio gestito l’aggiornamento passa dal fornitore. Per Supabase la documentazione sugli upgrade descrive un aggiornamento avviato da te, con lo stesso processo per major e minor: si parte dal pulsante “Upgrade project” nelle impostazioni generali del progetto, e durante l’operazione il progetto va offline. Non ho verificato da quando Supabase offra le versioni corrette: la prima query di questo articolo ti dice se il tuo progetto le ha già.
Se sei ancora su PostgreSQL 14
La 14.25 chiude le falle di novembre, ma è l’ultima. La prossima vulnerabilità che toccherà la 14 resterà aperta. Il passaggio a una major supportata non si fa cambiando i binari: serve pg_upgrade oppure un dump e un restore, con una prova completa dell’applicazione prima di farlo in produzione.
Ogni major è supportata per cinque anni dalla prima release, e la pagina delle versioni riporta le date: la 17 fino all’8 novembre 2029, la 18 fino al 14 novembre 2030. Io sceglierei la 18 e lascerei la 19 a quando avrà avuto la sua prima correzione, ma è una preferenza: dipende da quanto tempo hai per i test.
Da dove cominciare
Se hai più database da aggiornare, parti da quelli dove la terza query trova ruoli usati da utenti che si registrano da soli. Chi ha un’app su PostgreSQL 14 deve mettere in calendario la migrazione, non solo la patch: il costo di quel lavoro rientra nella manutenzione di cui parlo nell’articolo su quanto costa un gestionale personalizzato.
Se il tuo gestionale o la tua area riservata stanno su Postgres, scrivimi: guardo versione e permessi del database e ti dico cosa serve.
Continua a leggere

PHP2Shell: come capire se il tuo PHP ha davvero la patch
PHP2Shell tocca quasi ogni sito in PHP, WordPress compreso. Come leggere la versione vera sul server, perché il numero inganna e cosa fare con PHP 7.
10 min di lettura
La fine delle recensioni a 5 stelle
Tra bot e voti sollecitati, le recensioni perfette non convincono più. Ecco perché la trasparenza reale batte le 5 stelle finte.
5 min di lettura
Web app o app nativa: quale serve alla tua attività
Web app o app nativa per clienti e collaboratori: cosa fa oggi una web app sul telefono, cosa chiedono Apple e Google, quando serve davvero lo store.
10 min di lettura