AI-generated analysisPublished automatically and not human-verified. Validated context appears in community notes below.
← Watch feed
Critical 88 Bitcoin

Validate Esplora merkle proof against the block header's merkle root

Public commit record

What the developer wrote

Authored by Elias Rohrer

78/100 · Adequate
Validate Esplora merkle proof against the block header's merkle root

`EsploraSyncClient::get_confirmed_tx` parsed the SPV proof returned by
the Esplora server but threw away the security check: the merkle root
computed by `PartialMerkleTree::extract_matches` was discarded
(`let _ = …`), and only the leaf-equality check (`matches[0] == txid`)
remained. Anyone can construct a single-leaf partial tree advertising
an arbitrary txid via `PartialMerkleTree::from_txids(&[txid], &[true])`,
so this gate was vacuous.

A malicious or compromised Esplora server could therefore convince
`EsploraSyncClient` that any transaction was confirmed in any block by
returning `MerkleBlock { header: real_header, txn: forged_partial_tree }`,
causing LDK to feed a synthesized `ConfirmedTx` into `Confirm`
implementations such as `ChannelManager` / `ChainMonitor`. From there,
the channel-funding / closing / HTLC flows would treat the transaction
as confirmed at an attacker-chosen height, with consequences ranging
from premature state transitions to force-close races.

Capture the merkle root returned by `extract_matches` and require it
to equal `block_header.merkle_root`, matching the validation the
Electrum sibling already performs via `validate_merkle_proof`.

Co-Authored-By: HAL 9000
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Names security-relevant behavior explicitly
The short version

What changed, and why it matters

This commit fixes a security bug in LDK's Esplora client. The client was supposed to verify that a transaction was really included in a Bitcoin block by checking a cryptographic proof (a merkle proof) from the Esplora server. But it only checked that the proof contained the right transaction ID, not that the proof actually connected to the real block header. Because a single-leaf proof can be forged for any transaction ID, a malicious or compromised Esplora server could trick LDK into believing any transaction was confirmed in any block. That could trigger wrong channel state changes, premature force-closes, or other fund-risking behavior. The fix makes the client compare the computed merkle root from the proof against the block header's merkle root, which is the same check the Electrum client already did.

Recommended action

Upgrade to a rust-lightning release containing this commit. If running an LDK node that uses EsploraSyncClient, treat any transaction confirmations received before the patch as potentially attacker-chosen and avoid relying on them for irreversible channel actions. Consider switching to Electrum or a trusted Bitcoin RPC source as a temporary mitigation if patching is delayed.

Security signals we found

01

Missing cryptographic root-of-trust validation (merkle root discarded)

02

Single-party server (Esplora) could forge transaction confirmation

03

Forged confirmation propagates into Confirm implementations (ChannelManager / ChainMonitor)

04

Could cause premature channel state transitions and force-close races

05

Fix aligns Esplora validation with existing Electrum validation

Risk score

Why this scored 88/100

Our methodology →
Potential impact 27/30
Exploitability 22/25
Stealth signal 12/15
Affected reach 13/15
Confidence 9/10
Evidence quality 5/5
Human-validated context

Community notes

Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.

No validated notes yet.

The AI analysis stands alone for now. Submit a note if you can add evidence or important context.