What changed, and why it matters
This commit removes the ability of Electrum's Lightning peer code to decompress routing data using zlib. The change follows an updated Lightning protocol rule (BOLT 7) that says uncompressed routing data must be used. Keeping zlib support could, in theory, allow a malicious peer to send a specially crafted compressed payload that causes crashes, excessive memory use, or other unexpected behavior. The patch is straightforward and defensive, but it is a partial removal: it only stops accepting compressed data and does not add broader input-size checks.
Apply the patch to remove zlib support. As a follow-up, consider adding an explicit length check in decode_short_ids() to ensure the encoded payload size is a multiple of 8 plus 1, and bound the number of IDs parsed to prevent memory exhaustion from a malicious peer.
Security signals we found
Removal of untrusted zlib decompression path
Protocol compliance update to BOLT 7
Potential denial-of-service surface from compressed input eliminated
No explicit length validation added for remaining uncompressed path
Evidence from the diff
In electrum/lnpeer.py, decode_short_ids() previously accepted two first-byte values: 0 for uncompressed and 1 for zlib-compressed short channel IDs. The patch removes the zlib import and the zlib.decompress() branch, so any first byte other than 0 now raises an exception. This aligns with BOLT 7’s requirement that short channel IDs in channel range replies no longer use compression. The function is also made a staticmethod. The security benefit is eliminating an attack surface involving untrusted compressed input; however, the function still does not validate the total length or bound memory allocation before slicing.
Changed components
electrum/lnpeer.pyLightning peer channel range query handlingdecode_short_ids()Inspect captured patch +4 / −7
diff --git a/electrum/lnpeer.py b/electrum/lnpeer.py
index fe0516b..98e3a29 100644
--- a/electrum/lnpeer.py
+++ b/electrum/lnpeer.py
@@ -4,7 +4,6 @@
# Distributed under the MIT software license, see the accompanying
# file LICENCE or http://www.opensource.org/licenses/mit-license.php
-import zlib
from collections import OrderedDict, defaultdict
import asyncio
import os
@@ -786,13 +785,11 @@ class Peer(Logger, EventListener):
first_blocknum=first_block,
number_of_blocks=num_blocks)
- def decode_short_ids(self, encoded):
- if encoded[0] == 0:
- decoded = encoded[1:]
- elif encoded[0] == 1:
- decoded = zlib.decompress(encoded[1:])
- else:
+ @staticmethod
+ def decode_short_ids(encoded):
+ if encoded[0] != 0:
raise Exception(f'decode_short_ids: unexpected first byte: {encoded[0]}')
+ decoded = encoded[1:]
ids = [decoded[i:i+8] for i in range(0, len(decoded), 8)]
return ids
Why this scored 33/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.