pull down to refresh

This is how the lnp2pbot lost funds (#1544986).

Invoices could contain multiple payment hashes. If your lightning node picked a different payment hash than you expected, then you could end up with a mismatch between what your software thought it had paid and what the node actually paid.

It's a bit like the third-party transaction malleability that was fixed by SegWit, except that in this case, the "third party" is the software library you used. Here, it was invoices.

In this PR, we modify the spec to reject an invoice with duplicate payment hashes.
Unfortunately, there was a recent hack of a popular Telegram P2P bot that exploited this ambiguity. Some libraries took the first payment hash, while some took the last. If you were running a system that exhibited both variants of the behavior (e.g. a difference between libraries or nodes), then your system could be tricked into thinking it had never paid out a withdrawal, thereby leading to a vulnerability that could drain the system.
IMO, there's no reason an invoice should have >1 payment hash, so we should just reject it.
Test vectors have been updated accordingly.

I feel good and bad because I was close to finding this a year ago, see my review comment.


AFAIK, Stacker News is NOT vulnerable to this. It might have been vulnerable before 758c9866 (Aug. 6, 2026), when @k00b seems to have added some reasonable paranoia around payments, around the same time lnp2pbot got attacked. Maybe he was tipped off?

130 sats \ 8 replies \ @anon 18 Sep

The impact of this is greater than invoices. It takes an application's decoder picking the wrong hash when there are multiple. How many library authors considered there being more than one hash?

If I knew about this bug, I wouldn't attack lnp2pbot first...but they were the first to irresponsibly disclose.

reply

Good point! How many libraries are there per language?

but they were the first to irresponsibly disclose.

I wasn't even sure if I should post this. But since it didn't seem like they were trying to hide the vuln anymore, I also didn't try to hide it.

reply
30 sats \ 1 reply \ @anon 18 Sep

More than one.

reply
105 sats \ 0 replies \ @ek OP 18 Sep

Okay, that was a dumb question from me, haha.

I was writing a BOLT11 parser for fun when I got confused by this. So there are probably a lot of broken BOLT11 parsers (in any language) out there.

reply
30 sats \ 4 replies \ @anon 18 Sep
I wasn't even sure if I should post this.

I wouldn't unless I knew everything was patched but it's a brave new world.

it didn't seem like they were trying to hide the vuln anymore

They are irrelevant. They shutdown. They pouted and laid blame. They are not everyone impacted by this.

reply

I mean the lightning devs, see GitHub PR.

Sorry if I should have kept a low profile, I'm still learning (a lot).

unless I knew everything was patched

How/when do you know that?

reply
30 sats \ 2 replies \ @anon 18 Sep

It was fucked already anyway. Red team is the example of responsible now.

reply
Red team is the example of responsible now.

Please, no?

reply

Well, I guess I should go through everything I found confusing about the lightning spec again and look at it with an adversarial mindset, rather than just thinking, “Damn, this sucks to implement.” I think I wasn't expecting to find a vuln in something as superficial as parsing a BOLT11 invoice (compared to everything that's going on in lightning), so I didn't look at things from the right perspective.

reply