-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
zpay32: Fix broken last tagged field #3767
Conversation
This switches the applicable error to use an exported sentinel error so that it is more testable.
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.
This adds tests for checksum malleability issue of bech32 strings as used by LN invoices.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Indeed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@matheusd nice work! one small comment on the checksum unit test
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