Tornar al Blog

«La columna estava xifrada»: pgcrypto desava text pla i ningú no se n'assabentava

«La columna estava xifrada»: pgcrypto desava text pla i ningú no se n'assabentava

El 13 d'agost PostgreSQL va publicar 18.6, 17.11, 16.15, 15.19 i 14.24 i va tancar 28 vulnerabilitats i més de 110 errors de cop. Dotze de les vint-i-vuit són desbordaments de memòria, i cinc més confusions de tipus, amb títols gairebé intercanviables. Una no s'assembla a cap. La CVE-2026-14663 diu que, en certes condicions, pgcrypto escrivia text pla a la columna que et pensaves que estava xifrada. Sense error, sense avís, sense res al registre.

Les notes de la versió 18.6 ho expliquen sense anestèsia: «Previously, if OpenSSL rejected the requested cipher (for example, because it is running in FIPS mode, or the legacy provider hasn't been loaded), pgcrypto failed to notice the failure and simply XOR'd the non-encrypted block with the plaintext, rendering the "encryption" trivially breakable». És a dir: pgcrypto demanava a OpenSSL un algorisme, OpenSSL responia que no, pgcrypto no llegia la resposta i tirava endavant. El que acabava al bytea no era text xifrat: era la dada amb una capa de XOR sobre un bloc que mai no es va arribar a xifrar.

La fitxa del CVE tanca el cercle amb una frase que no admet lectura amable: la fallada «allows a user to recover cleartext, via direct observation of the faulty ciphertext». Mirant la dada desada. I hi ha una segona part, per si la primera es quedava curta: «If the application accepts encrypted data as input, decryption will succeed even with the wrong key». La clau havia deixat d'importar. Les funcions afectades són les vuit de PGP: pgp_sym_encrypt, pgp_pub_encrypt, les seves parelles de desxifrat i les quatre variants _bytea.

Abans que s'escampi el pànic: per defecte, bé

Això no li passa a tothom, i convé dir-ho abans que res. L'algorisme per defecte de pgp_sym_encrypt és aes128, i AES està disponible a qualsevol OpenSSL modern. Els algorismes que disparen la fallada són els vells: les notes de versió citen blowfish/bf, twofish, cast5 i 3des. PostgreSQL li posa un 6,5 de CVSS, i el número té la seva lògica: cal que es donin les dues condicions alhora. Si la teva aplicació mai no ha escrit l'opció cipher-algo, gairebé segur que això no va amb tu. Gairebé: aquestes opcions només manen sobre el que xifres tu. «Decrypt functions get the parameters from the PGP data», diu la documentació. Si la teva aplicació desxifra missatges PGP que arriben de fora, l'algorisme el va triar qui els va crear, i fins allà no hi arriba cap grep del teu repositori.

La part incòmoda arriba després. Ningú no escriu cipher-algo=bf el 2026. Es va escriure fa més d'una dècada, copiat d'un exemple que llavors era raonable, i encara hi és perquè la columna es llegia bé i ningú no va tenir motiu per tornar-hi. Els llocs on apareix aquesta cadena solen ser els mateixos: integracions amb GnuPG antic, importadors de fitxers d'un altre proveïdor, procediments emmagatzemats que van sobreviure a tres migracions.

El dia que es va trencar no va ser el dia que es va escriure

El codi que demana Blowfish pot haver estat xifrant correctament durant anys. El que canvia no és l'aplicació: és la màquina de sota. La documentació de pgcrypto ho avisa en una línia: «When compiled against OpenSSL 3.0.0 and later versions, the legacy provider must be activated in the openssl.cnf configuration file in order to use older ciphers like DES or Blowfish». OpenSSL 3 va enviar Blowfish i CAST5 al proveïdor legacy, que no es carrega sol; 3DES es queda al proveïdor per defecte i desapareix per una altra porta, la del mode FIPS. Dos camins diferents cap al mateix lloc.

Ajunta les dues peces i surt una escena que hem vist moltes vegades amb altres noms: algú migra el servidor de base de dades a una distribució més nova un dissabte al matí. L'aplicació no es toca. Els tests passen, perquè els tests xifren i desxifren amb el mateix servidor —xifren malament i desxifren malament, de manera perfectament coherent—. Res no cau, res no apareix a la monitorització, ningú no obre un tiquet. I des d'aquell dissabte, el que entra en aquesta columna es pot llegir. Ja vam escriure aquí sobre un control que fallava obrint; aquest ni tan sols falla: retorna OK.

La bona notícia: a partir d'ara es trenca

La solució, signada per Daniel Gustafsson, fa l'única cosa sensata: convertir el silenci en soroll. «By default, pgcrypto will now fail to decrypt any messages that were affected in this way». Traduït: actualitzes el servidor i, si tenies el problema, l'aplicació deixa de llegir aquesta columna. Un dilluns al matí, amb un tiquet. Aquest tiquet és el detector més barat que tindràs aquest mes, i ve dins del paquet: si després d'actualitzar res no deixa de desxifrar-se, tampoc no tenies la fallada. Si alguna cosa deixa de desxifrar-se, ja tens per on començar a mirar.

La sortida d'emergència i la seva lletra petita

Per recuperar les dades que van quedar així, PostgreSQL ha afegit una opció nova a pgp_sym_decrypt i pgp_pub_decrypt: ignore-cipher-failure=1, que restaura el comportament anterior i permet treure l'embolcall defectuós per tornar a xifrar amb un algorisme modern. La documentació l'obre amb la paraula «Dangerous!» i hi afegeix la frase que cal llegir a poc a poc: «Such faulty messages do not require the correct decryption key when ignore-cipher-failure is enabled, so there is no guarantee that the decrypted plaintext actually originated from a holder of the key». Per treure aquelles dades no cal la clau. Que és una altra manera de dir el mateix d'abans: no estaven xifrades.

I hi ha una restricció d'ordre que es passa per alt amb facilitat: «It is important however that the behavior of OpenSSL be the same as it was when the faulty messages were created: if the set of unsupported algorithms is not the same, this approach will not work». El rescat s'ha de fer on es va espatllar, amb el mateix OpenSSL a sota. Si el pla era «actualitzem el servidor, el movem a la màquina nova i després, amb calma, mirem això de la columna», el pla està del revés. Primer es rescata i es torna a xifrar amb aes256; després es muda.

I convé no barrejar dos casos que des de fora s'assemblen molt. Un és el missatge que es va xifrar malament, i és el que arregla aquesta opció. L'altre és el missatge que es va xifrar bé, amb un algorisme que avui el teu OpenSSL no ofereix; aquí la documentació és taxativa: ignore-cipher-failure «is not necessary or helpful for that scenario», i el que toca és habilitar el proveïdor que falta. Si tot i així es fa servir l'opció i el missatge ben xifrat passa les comprovacions d'integritat de PGP, «that result is coincidental and does not make the recovered plaintext trustworthy». Et pot tornar una cosa amb bona pinta que no ho sigui.

Quina versió tens de debò

Aquí hi ha dues trampes, i totes dues afecten la manera com comproves si estàs al dia. La primera és a la mateixa fitxa oficial del CVE, que diu: «Versions before PostgreSQL 18.5, 17.11, 16.15, 15.19, and 14.24 are affected», i llista 18.5 com a versió corregida. 18.5 no existeix. L'anunci del mateix dia ho explica: «This release skips PostgreSQL 18 versions from PostgreSQL 18.4 to 18.6. 18.5 was not shipped due to a regression». Si el teu inventari busca el número que posa la fitxa, no el trobarà mai. Per a la branca 18 el número bo és 18.6.

La segona trampa és d'on vénen els teus paquets. Ho hem mirat avui, 20 d'agost a la tarda, contra els repositoris públics, i no és el mateix:

  • PGDG (apt.postgresql.org), per a bookworm i trixie: ja serveix les versions corregides de les cinc branques — 14.24, 15.19, 16.15, 17.11 i 18.6 (a trixie, 17.11-1.pgdg13+2).
  • Debian 13 (trixie), repositori principal: postgresql-17 continua a 17.10-0+deb13u1, que el rastrejador de seguretat de Debian marca com a vulnerable. L'arranjament va pel canal de seguretat: 17.11-0+deb13u1, publicat com a DSA-6438-1. Si aquesta màquina no té la línia trixie-security al seu sources.list, avui continua amb la fallada.
  • Debian 12 (bookworm): el mateix amb postgresql-1515.18 al principal, 15.19-0+deb12u1 a seguretat, com a DLA-4740-1.
  • Si continues a PostgreSQL 13 (bullseye), el rastrejador el dona per vulnerable i sense versió corregida. Allà no hi ha pedaç per aplicar: hi ha una migració per planificar. I per a qui estigui a la branca 14, convé apuntar-ho ja: PostgreSQL 14 deixa de rebre arranjaments el 12 de novembre del 2026.

I el paper que diu que estava xifrat

Si al registre d'activitats de tractament, a la política de seguretat o a l'última resposta a un qüestionari de client hi ha una línia que diu «les dades sensibles s'emmagatzemen xifrades a la base de dades», aquesta línia pot haver deixat de ser certa el dia que aquesta màquina va canviar d'OpenSSL. L'article 34.3.a) del RGPD permet estalviar-se la comunicació als afectats quan les mesures aplicades feien les dades inintel·ligibles per a qui no hi està autoritzat, i posa el xifratge com a exemple. Un XOR que es desfà sense clau difícilment hi encaixa.

No som advocats i aquesta valoració no ens pertoca. El que sí que és nostre és el que hi ha a sota: qui hagi de decidir necessita saber quin algorisme demanava l'aplicació, quin OpenSSL hi havia en aquesta màquina i des de quina data. Les tres coses es reconstrueixen —el codi, l'openssl.cnf, la data del canvi de sistema operatiu—, i surten molt millor reconstruïdes avui, amb calma, que dins d'un expedient amb termini de setanta-dues hores.

Què faríem aquesta setmana

  • Buscar la cadena, no el CVE. grep -ri "cipher-algo" al codi, als procediments emmagatzemats i als jobs d'importació. Si no apareix, l'assumpte està tancat i has trigat deu minuts.
  • Mirar el servidor, no l'aplicació. SELECT version(); contrastat amb 18.6 / 17.11 / 16.15 / 15.19 / 14.24, i una ullada a si l'openssl.cnf d'aquesta màquina carrega el proveïdor legacy. Les dues respostes juntes diuen si la fallada hi era possible.
  • Deixar que el pedaç faci d'auditor. Actualitzar primer una còpia de la base i llegir les columnes afectades. El que deixi de desxifrar-se és la llista de feina, amb la reserva d'abans: pot ser una dada mal xifrada o una de ben xifrada amb un algorisme que ja no està carregat, i no es tracten igual.
  • Rescatar abans de mudar. Si cal fer servir ignore-cipher-failure, a la màquina d'origen i amb el seu OpenSSL. Tornar a xifrar amb aes256, i anotar qui, quan i sobre quines files: això és el que es demanarà després.
  • I ja de pas, preguntar per la clau. pgcrypto treballa dins del servidor, i la seva documentació ho diu sense embuts: «all the data and passwords move between pgcrypto and client applications in clear text», i per això cal «[t]rust both system and database administrator». Si aquesta columna desa el que sospitem, el debat no era només l'algorisme. Del mateix calaix: el panell de dades que també era el clauer, i el fitxer que deia ser un PNG.

El que és rar d'aquesta vulnerabilitat és que no necessita que ningú t'ataqui per fer-te mal. No hi ha explotació en curs, no hi ha campanya, no hi ha actor amb nom d'animal. Hi ha una columna que pot portar anys desant en clar exactament allò que s'hi va posar perquè no es llegís, i només una persona al món ho pot descobrir: la que s'assegui a mirar-la. La versió nova ajuda de l'única manera en què un programa pot ajudar en això — per fi es queixa.

Fonts (verificades el 20 d'agost del 2026): la data, les versions publicades, les 28 vulnerabilitats i els més de 110 errors, la frase sobre la 18.5 no publicada i el final de suport de PostgreSQL 14, de l'anunci oficial del 13 d'agost del 2026. La descripció de la fallada, les funcions afectades, la frase sobre la clau incorrecta i les versions «before 18.5, 17.11, 16.15, 15.19, and 14.24», de la fitxa de CVE-2026-14663. L'explicació del XOR, la llista d'algorismes que el disparen, l'autoria de Daniel Gustafsson i el comportament nou en desxifrar, de les notes de la versió 18.6. L'algorisme per defecte, l'advertiment sobre el proveïdor legacy d'OpenSSL 3, l'avís «Dangerous!» d'ignore-cipher-failure, la frase sobre la clau no necessària, la condició que OpenSSL es comporti igual i les limitacions de seguretat citades, de la documentació de pgcrypto. L'estat per distribució, el DSA-6438-1 i el DLA-4740-1, del rastrejador de seguretat de Debian. Són nostres les consultes d'avui als índexs públics d'apt.postgresql.org (branques trixie-pgdg i bookworm-pgdg); són reproduïbles i donen la mateixa resposta des de qualsevol lloc. És nostra també la lectura sobre l'escenari de la migració de sistema operatiu, declarada com a lectura al text. Les citacions es deixen en anglès, el seu idioma original, perquè es puguin verificar paraula per paraula.

Saps quin algorisme demana la teva aplicació?

Mantenim bases de dades i aplicacions de negoci que porten anys en producció, amb la part avorrida escrita: quina versió corre, de quin repositori ve i què es recolza en què. Si aquesta setmana toca obrir la caixa d'una columna xifrada que ningú no ha mirat des de fa temps, és exactament la feina que fem a dades i aplicacions, i la part de decidir què es documenta i què es notifica, a compliment i continuïtat.

Parlar amb everyWAN

Etiquetes:

Compartir:

Subscriu-te al nostre butlletí

Per rebre històries del món IT, novetats d'everyWAN i ofertes exclusives per a subscriptors, dona't d'alta a la nostra llista de correu

everyWAN
everyWAN