Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
zpay32: Fix broken last tagged field #3767
This fixes an issue with bech32 decoding where inserting a specific character in the checksum might generate a valid signature albeit with a different destination node than the original invoice.
This fixes the issue by ensuring that the last tagged field has all the required data instead of silently discarding a partial field, such as a field with only a type element but no length elements.
I tested this behavior in other implementations. c-lightning and lightning-payencode (python) fail to decode invoices with a partial field. Bolt11 (node) accepts it.
This should probably be clarified in BOLT-11 so that the behavior is consistent across implementations.
For context: sipa/bech32#51
This fixes an issue where the last tagged field of an invoice could get broken due to the malleability of bech32 checksums. The addition of a specific character in the second to last position of the checksum could cause the previous signature field to mutate and thus point to a different public node.
halseth left a comment
Excellent PR! LGTM
It's an interesting observation, that the signature can be changed this way while keeping the invoice valid. We could start adding the tagged field for pubkey by default to mitigate, but if someone can modify an invoice like this to change the destination, they probably can also just resign the invoice.
Other options (but these involves changing BOLT-11) would be to include the length of tagged data as a prefixed field (along with the timestamp) or as a new tagged field. These have the advantage of being smaller than the pubkey.