Check Esplora Merkle leaf risk by base size
What changed, and why it matters
This commit fixes a guard condition in LDK's Esplora transaction-sync code. The code tries to skip 64-byte transactions because such transactions can be abused in a known Bitcoin Merkle-tree weakness. The bug was that it measured total transaction size, which includes witness data. A transaction with witness data could be larger than 64 bytes in total size while still having a 64-byte non-witness serialization, so the guard could be bypassed. The fix uses a helper that checks the base (non-witness) size instead.
Review the implementation of is_potentially_unsafe_merkle_leaf to confirm it checks base (non-witness) transaction size and that no other sync clients use total_size for the same guard. Consider adding regression tests with segwit transactions whose base size is 64 bytes but total_size is larger.
Security signals we found
Bypass of explicit security guard
Witness vs non-witness size confusion
Merkle leaf weakness protection
Transaction confirmation validation
Evidence from the diff
In lightning-transaction-sync/src/esplora.rs, the confirmation check used tx.total_size() == 64 to detect the 64-byte Merkle leaf risk described in bitslog.com/2018/06/09/leaf-node-weakness-in-bitcoin-merkle-tree-design. Because txid and Merkle hashing use the non-witness serialization (base size), witness padding can make total_size exceed 64 while the base size remains 64. The patch replaces the total_size comparison with is_potentially_unsafe_merkle_leaf(&tx), which presumably checks base_size == 64. This closes a bypass of the safety check.
Changed components
lightning-transaction-sync/src/esplora.rsEsploraSyncClient confirmation logicInspect captured patch +2 / −2
diff --git a/lightning-transaction-sync/src/esplora.rs b/lightning-transaction-sync/src/esplora.rs
index 52cfb39..07d2ba2 100644
--- a/lightning-transaction-sync/src/esplora.rs
+++ b/lightning-transaction-sync/src/esplora.rs
@@ -5,7 +5,7 @@
// http://opensource.org/licenses/MIT>, at your option. You may not use this file except in
// accordance with one or both of these licenses.
-use crate::common::{ConfirmedTx, FilterQueue, SyncState};
+use crate::common::{is_potentially_unsafe_merkle_leaf, ConfirmedTx, FilterQueue, SyncState};
use crate::error::{InternalError, TxSyncError};
use lightning::chain::WatchedOutput;
@@ -393,7 +393,7 @@ impl<L: Logger> EsploraSyncClient<L> {
// https://web.archive.org/web/20240329003521/https://bitslog.com/2018/06/09/leaf-node-weakness-in-bitcoin-merkle-tree-design/).
// To protect against this (highly unlikely) attack vector, we check that the
// transaction is at least 65 bytes in length.
- if tx.total_size() == 64 {
+ if is_potentially_unsafe_merkle_leaf(&tx) {
log_error!(
self.logger,
"Skipping transaction {} due to retrieving potentially invalid tx data.",
Why this scored 59/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.