lnpeer: forwarding: dont release preimage if dont_settle_htlc
What changed, and why it matters
This commit fixes a bug in Electrum's Lightning Network payment forwarding. Normally, Electrum can mark certain payment hashes as 'do not settle' (dont_settle_htlcs), meaning it should not reveal the secret preimage that unlocks a payment. However, the old code would reveal that secret anyway when the payment was being forwarded through the node, not just when the node was the final recipient. The fix checks the 'do not settle' list before releasing the preimage, even during forwarding.
Treat as a security-relevant bug fix. Users running Lightning nodes on affected versions should upgrade. Review whether any other preimage-release paths similarly bypass dont_settle_htlcs.
Security signals we found
Preimage disclosure control bypass in forwarding path
Logic gap between local HTLC settlement policy and forwarding behavior
Fix adds explicit guard before get_preimage() call
Evidence from the diff
In electrum/lnpeer.py, within the forwarding path of an HTLC (multi-part payment resolution), the code previously called self.lnworker.get_preimage(payment_hash) unconditionally after a successful forwarding set. The patch adds a guard: if payment_hash.hex() is present in self.lnworker.dont_settle_htlcs, the function returns (None, None, None) without fetching or returning the preimage. This prevents preimage disclosure for payment hashes the wallet operator has explicitly flagged to not settle, closing a logic gap between local receive behavior and forwarding behavior.
Changed components
electrum/lnpeer.pyLightning Network HTLC forwarding / MPP resolutionInspect captured patch +4 / −1
diff --git a/electrum/lnpeer.py b/electrum/lnpeer.py
index fe0516b..ecc1e98 100644
--- a/electrum/lnpeer.py
+++ b/electrum/lnpeer.py
@@ -3240,7 +3240,10 @@ class Peer(Logger, EventListener):
# this was a forwarding set and it failed
self.lnworker.set_mpp_resolution(payment_key, RecvMPPResolution.FAILED)
return error_bytes or failure_message, None, None
- preimage = self.lnworker.get_preimage(mpp_set.get_payment_hash())
+ payment_hash = mpp_set.get_payment_hash()
+ if payment_hash.hex() in self.lnworker.dont_settle_htlcs:
+ return None, None, None
+ preimage = self.lnworker.get_preimage(payment_hash)
return None, preimage, None
return None
Why this scored 58/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.