lnonion: explicitly forbid nesting trampoline-in-trampoline
What changed, and why it matters
This commit adds a safety check in Electrum's Lightning code to block a 'trampoline inside trampoline' payment routing scenario. The developer states they don't want to reason about what could go wrong without this guard. The current code already uses fixed-size onions that would likely prevent the nested case, but a future protocol change may allow variable-size trampoline onions, so this assert is added defensively.
Treat as a low-confidence hardening patch. Review whether nested trampoline onions could enable routing loops, fee extraction, or privacy degradation. If a security issue is suspected, request a security advisory or CVE from the maintainers; otherwise, include in normal release notes as a defensive fix.
Security signals we found
Defensive assert added to prevent nested trampoline onion routing
Developer explicitly states they don't want to reason about consequences without the check
Future protocol change (variable-size trampoline onions) motivates the guard
No CVE, advisory, or researcher attribution present in commit
Evidence from the diff
In electrum/lnonion.py, process_onion_packet() now raises an exception if a trampoline onion packet is found while is_trampoline is already true. This prevents nested trampoline routing. The change is defensive: existing fixed 400-byte trampoline onions implicitly prevent nesting, but the BOLT PR for variable-size trampoline onions removes that implicit protection, making the explicit check necessary.
Changed components
electrum/lnonion.pyLightning trampoline routing / onion processingInspect captured patch +2 / −0
diff --git a/electrum/lnonion.py b/electrum/lnonion.py
index 2f53b36..a2f1a56 100644
--- a/electrum/lnonion.py
+++ b/electrum/lnonion.py
@@ -396,6 +396,8 @@ def process_onion_packet(
# trampoline
trampoline_onion_packet = hop_data.payload.get('trampoline_onion_packet')
if trampoline_onion_packet:
+ if is_trampoline:
+ raise Exception("found nested trampoline inside trampoline")
top_version = trampoline_onion_packet.get('version')
top_public_key = trampoline_onion_packet.get('public_key')
top_hops_data = trampoline_onion_packet.get('hops_data')
Why this scored 41/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.