Dear list,

earlier last month, our team at LNbits discovered a rather interesting exploit 
which wich would enable an attacker to create balances out of thin air by 
abusing a quirk in how invoices are handled internally. We've patched this in 
LNbits version 0.10.5 and urge anyone to update ASAP if you haven't done so 
already. I want to describe the attack here, since my gut feeling is that 
carrying out the same exploit is possible in other Lightning applications. If 
you're working on custodial wallets, payment processors, account management 
software, etc. you probably want to read this.

In short, the attacker was able to insert a bolt-11 payment hash of payment A 
into a different payment, creating a malicious invoice B that can trick the 
backend into believing that B == A.

Here is how it goes:

- Attacker creates invoice A of amount 1000 sat in LNbits
- Attacker creates invoice B' of amount 1 sat on her own node
- Attacker deserializes B', inserts payment_hash(A) into payment_hash(B), 
re-signs the invoice, and serializes it again, producing malicious invoice B
- Attacker creates a new account in LNbits and pays B

- LNbits backend uses payment_hash(B) to check whether this is an internal 
payment or a payment via LN
- Backend finds A in its database since we implicitly assume that 
payment_hash(A) commits to A

** This is the critical part! Payment hashes do *NOT* commit to any payment 
details (like amount) but only to the preimage! ** 

- Backend settles payment internally by crediting A debiting B
- Attacker has "created" 999 sats

Mitigation:

The mitigation is quite simple. Backends should either use self-generated 
unique "checking id's" for looking up internal payments or use additional 
checks to make sure that the invoice details have not been messed around with 
(e.g., asserting amount(A) == amount(B)).

Lessons:

I think there are two lessons here. First, it's good to realize the level of 
sophistication of LN-savvy attackers. This attack clearly involves a 
fundamental understanding of bolt-11 and requires custom tooling to produce the 
malicious invoice. 

The second lesson is more valuable: The "payment hash" of an invoice is not a 
"payment" hash but merely a "preimage" hash – and nothing else. Naming this 
field as such increases the chance of developers implicitly assuming that the 
hash commits to payment details like amount, pubkey, etc. I will from now on 
call this simply the "preimage hash" and invite you to do so too.

Best 

Calle
_______________________________________________
Lightning-dev mailing list
Lightning-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev

Reply via email to