
CVE-2026-107846 è una vulnerabilità critica (CVSS 4.0: 9.3) nella libreria JavaScript bitcoinjs-lib, usata in Node.js e nel browser per lavorare con Bitcoin. La verifica del Merkle root di un blocco non rileva le transazioni duplicate: un peer può consegnare un blocco con una lista di transazioni diversa da quella onesta mantenendo lo stesso root, lo stesso header, la stessa proof of work e lo stesso identificativo di blocco. Le versioni corrette sono 5.2.1, 6.1.8 e 7.0.2. Se la tua applicazione indicizza blocchi, fa da explorer, da indexer per un exchange o da client SPV, aggiorna e verifica i dati già processati.
Cosa è successo: la vulnerabilità CVE-2026-107846 in bitcoinjs-lib
La funzione fastMerkleRoot di bitcoinjs-lib costruisce l'albero di Merkle di un blocco. Quando un livello dell'albero ha un numero dispari di nodi, l'ultimo nodo viene hashato con se stesso. È il comportamento previsto dal protocollo, ma la libreria non segnalava la presenza di coppie di hash adiacenti identiche. Il risultato è che una lista di transazioni con duplicati in coda produce esattamente lo stesso root della lista originale.
Il verificatore del root di blocco è stato introdotto come Block.checkMerkleRoot() insieme a Block.calculateMerkleRoot(). Nelle versioni più recenti la validazione passa per checkTxRoots() e __checkMerkleRoot. Tutti questi percorsi accettavano un root ricalcolato senza controllare la mutazione della lista.
Chi è colpito: versioni vulnerabili di bitcoinjs-lib
Secondo l'advisory sono vulnerabili le versioni di bitcoinjs-lib dalla 2.3.0 fino alle release precedenti a:
- 5.2.1 per il ramo 5.x
- 6.1.8 per il ramo 6.x
- 7.0.2 per il ramo 7.x
Sei esposto se il tuo codice usa la libreria per validare blocchi ricevuti da terzi. Chi la usa solo per costruire e firmare transazioni, senza mai verificare un Merkle root, non è interessato da questo specifico difetto, ma conviene aggiornare comunque. Le categorie indicate dalle fonti come più a rischio sono explorer, indexer di exchange e client SPV.
Quanto è grave: punteggio CVSS e sfruttamento attivo
Il punteggio è 9.3 su scala CVSS 4.0, gravità critica. Il vettore è AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:H/VA:L/SC:N/SI:H/SA:H: attacco via rete, bassa complessità, nessun privilegio e nessuna interazione dell'utente. L'impatto principale è sull'integrità, alto sia sul sistema vulnerabile sia sui sistemi collegati.
Al momento la vulnerabilità non risulta nel catalogo CISA KEV. Non si tratta di esecuzione di codice remoto. Un attaccante che si presenta come peer può ottenere due effetti concreti:
- Far elaborare due volte la stessa transazione a un consumer che si fida del root, con possibili doppi accrediti nei saldi derivati.
- Far mettere in blacklist l'hash del blocco condiviso, con il rigetto del blocco onesto e una forma di negazione del servizio sulla sincronizzazione.
Come capire se sei esposto: verifica versione, esposizione e log
Versione installata
Nella cartella del progetto esegui npm ls bitcoinjs-lib (oppure yarn why bitcoinjs-lib o pnpm why bitcoinjs-lib). Il comando mostra anche le dipendenze transitive: altre librerie Bitcoin possono includerla senza che compaia nel tuo package.json. Controlla la versione risolta nel lockfile, non il range dichiarato.
Uso delle funzioni vulnerabili
Cerca nel codice e nelle dipendenze i riferimenti a checkMerkleRoot, calculateMerkleRoot, checkTxRoots e fastMerkleRoot. Se non c'è alcuna validazione di blocchi, il rischio è limitato. Se c'è, chiediti da dove arrivano i blocchi: da un nodo Bitcoin Core tuo e sotto il tuo controllo, oppure da peer P2P esterni o da API pubbliche. Nel secondo caso l'esposizione è reale.
Log e indicatori
Non esistono indicatori di compromissione pubblicati. Cerca nei tuoi dati e nei log:
- blocchi processati con txid ripetuti nella stessa lista di transazioni;
- transazioni accreditate o indicizzate più di una volta con lo stesso identificativo;
- hash di blocco finiti in blacklist o rigettati senza una causa chiara;
- divergenze tra la tua base dati e un nodo di riferimento alla stessa altezza di blocco.
Come risolvere la vulnerabilità: patch, aggiornamento e rimedio
La correzione è disponibile. Aggiorna al ramo che stai usando:
- npm install bitcoinjs-lib@5.2.1
- npm install bitcoinjs-lib@6.1.8
- npm install bitcoinjs-lib@7.0.2
I commit di correzione introducono un parametro mutated in calculateMerkleRoot(transactions, forWitness, mutated). Il calcolo del root segnala ora le coppie duplicate e __checkMerkleRoot restituisce vero solo se mutated.value è falso e il root coincide. Attenzione: se nel tuo codice chiami direttamente calculateMerkleRoot e confronti il risultato per conto tuo, l'aggiornamento della libreria non basta. Devi passare un oggetto { value: false } come terzo argomento e rigettare il blocco quando value diventa vero, oppure usare il metodo di verifica del blocco. Verifica poi il lockfile e ricostruisci l'immagine se usi Docker.
Per le dipendenze transitive che non puoi aggiornare subito, usa gli override del package manager (overrides in npm, resolutions in yarn) e testa il risultato. Ho descritto lo stesso approccio per un'altra libreria Node.js nell'articolo su CVE-2026-63395 in isomorphic-git.
Cosa fare subito: mitigazioni e hardening
In ordine di priorità, finché non hai aggiornato e verificato:
- Accetta blocchi solo da un nodo fidato. Se la tua applicazione legge da peer P2P esterni o da API pubbliche, instrada temporaneamente i blocchi attraverso un nodo completo che gestisci tu.
- Aggiungi un controllo sui txid duplicati prima della validazione del root: un blocco con lo stesso txid ripetuto va rigettato come malformato, non messo in blacklist per hash.
- Non bannare l'hash del blocco in caso di fallimento della verifica. L'hash è condiviso con il blocco onesto e il ban lo escluderebbe.
- Riconcilia saldi e indici con un nodo di riferimento per l'intervallo in cui il codice vulnerabile era in produzione.
- Aggiorna l'inventario delle dipendenze e attiva gli avvisi di sicurezza del repository, così la prossima volta la notifica arriva da sola.
Se sospetti una compromissione: incident response e analisi forense
Se trovi doppi accrediti, blocchi rigettati in modo anomalo o indici divergenti, non cancellare la base dati e non riavviare l'indicizzazione da zero prima di aver conservato lo stato attuale. Esporta e conserva i log dell'applicazione, del nodo e del reverse proxy con i relativi orari. Se i server sono accesi, lasciali accesi: una copia forense del disco e, dove possibile, della memoria permette di ricostruire da quali peer sono arrivati i blocchi alterati e quali transazioni sono state elaborate due volte.
Se gestisci fondi di terzi, valuta gli obblighi di comunicazione verso clienti, partner e autorità, inclusi quelli previsti da GDPR e NIS2 quando applicabili. Nel mio studio la gestione di un incidente di questo tipo rientra nell'incident response (da 1.500 a 3.000 € a seconda dell'ambito, preventivo a prezzo fisso) e, per la revisione del codice che tocca la validazione dei blocchi, nell'analisi software (da 1.000 a 4.000 €).
Fonti ufficiali
- Advisory GHSA-8vv3-6qpc-gpw6 su GitHub
- Commit 009f165: Detect duplicate pairs when computing Merkle roots
- Commit b79c771: Detect duplicate pairs when computing Merkle roots
- Commit f3434d1 di correzione
Hai bisogno di una verifica?
Se non sai se la tua applicazione usa bitcoinjs-lib per validare blocchi, o se vuoi una revisione indipendente del codice che gestisce transazioni e saldi, posso analizzarlo e dirti cosa correggere. Richiedi un preventivo gratuito con risposta entro 24 ore oppure scrivimi dalla pagina contatti, anche su WhatsApp.


