[Lightning-dev] CVE-2020-26896: LND Invoice Preimage Extraction

Conner Fromknecht conner at lightning.engineering
Tue Oct 20 21:52:29 UTC 2020

Hash: SHA256

Hi all,

Today we are writing to disclose the details of CVE-2020-26896 as a follow up to
the partial disclosure sent to lightning-dev [1].

## Abstract

Prior to v0.11.0-beta, an lnd node could be coerced into revealing an invoice
preimage for a forwarded HTLC with a colliding payment hash. This can be
exploited to a) weaken the victim's receiver privacy by confirming the
destination of an HTLC, and/or b) under certain circumstances, result in loss of
funds to the victim by believing the invoice was paid when it only received
routing fees. We have no evidence of either case being exploited in the wild.

It affects routing nodes, i.e. any lnd node that permits HTLC forwarding and
operates as any form of merchant node (accepts payment for goods & services);
nodes that use rejecthtlc=1 are not affected.

The vulnerability was reported privately to the lnd team by Antoine Riard.

## Background

When resolving incoming HTLCs on-chain, the forwarding node is expected to
supply a valid preimage via the witness in order to claim the HTLC. Preimages
can be learned in two primary ways: by generating an invoice or receiving a
preimage as the result of a successfully forwarded HTLC. Internally, lnd tracks
these differing preimage classes in two distinct places: an invoice database and
a preimage database.

For proper handling, a node should inspect the off-chain HTLC it received to
determine whether the node was an intermediary or the final hop (indicated by an
all zeros next_hop short channel id). Final hops are intended to consult the
invoice database for preimages, while intermediaries should consult the preimage

Earlier versions of lnd would incorrectly fallback to the invoice database if
the preimage database did not contain the preimage. This resulted in situations
where the node would reveal an invoice preimage, even though the victim was not
the final hop in a route.

In coordination with a triggered channel closure, an attacker can construct a
malicious HTLC through the victim, divulging the target invoice preimage
on-chain when the incoming HTLCis claimed. After disclosing the preimage, an
attacker can claim a concurrent outgoing HTLC whose CLTV has not yet expired.
his results in the HTLC's value being stolen, minus routing fees, since the
victim incorrectly believes they received the payment.

## Attack Scenario

An example of the attack goes as follows:

Assume a _real HTLC_ is routed to a malicious node, Malice, that has a channel
with sufficient outgoing bandwidth to forward to the victim, Bob, the intended
receiver of the payment.

Instead of forwarding the real HTLC, Malice creates a new _malicious HTLC_ which
has the same payment hash. The first hop’s amount should be equal or slightly
larger, the CLTV can be increased as desired up to default implementation

Malice forwards the malicious HTLC in a circular route through Bob and back to
herself, where she holds the malicious HTLC.

With the malicious HTLC locked in place, Malice triggers a unilateral close of
the Malice-Bob channel. The commitment played (from Bob’s POV) has an incoming
HTLC with the target invoice’s payment hash. The unilateral closure should be
initiated well before any of the malicious HTLC’s CLTVs expire, otherwise the
last channel in the route will also go to chain.

When the unilateral close is confirmed, Bob will promptly broadcast the
HTLC-success transaction for the malicious HTLC. Due to the bug, the preimage
provided to sweep the malicious HTLC is obtained from the invoice database as a
fallback to the (forwarded) preimage database, rather than being ignored.

The victim, Bob, has already marked the invoice settled and published the
preimage on-chain. However, the malicious HTLC is still active on Bob’s
downstream channel (and the rest of the circular route), allowing Malice to
settle the malicious HTLC she holds _after_ the invoice has already been marked
paid. This results in Bob only receiving routing fees, and the Malice
redirecting the payment to herself, while simultaneously convincing Bob of
receiving the full payment.

At this point, the malicious HTLC  has been successfully pulled from Malice to
herself in a circular route, making herself whole minus routing fees (in
addition to chain fees if she was the initiator of the Malice-Bob channel).
Malice then settles the real, intercepted HTLC using the same preimage to obtain
a profit.

### Caveats

For the attack to succeed, Malice must intercept a legacy HTLC or a
single-sharded MPP HTLC. If any other concurrent MPP shard has already reached
Bob before attempting to claim on-chain, the attack will fail due to additional
safety checks added to lnd [2], preventing an invoice from being settled by a
downgraded HTLC after it has already accepted an MPP shard with a valid payment

In order to directly profit from the attack, Malice must be intercepting a
payment from an unsuspecting victim, limiting control of timing and the amount
that can be siphoned. Malice must also somehow infer or guess that Bob has the
corresponding invoice being paid.

If Malice runs the same attack without intercepting a real HTLC, she pays
routing fees, and possibly chain fees, in exchange for the invoice preimage and
identity of the receiver. However, it is possible for her to indirectly profit
from this if the service provider releases tangible goods or services to anyone
with knowledge of the invoice preimage, which is not recommended in practice.

The upstream attacker does not need to be adjacent, they only need to know which
channel to target and watch for closure. Being adjacent increases the
assuredness of pulling off an exploit, but is not strictly required.

Similarly, the downstream attacker (possibly distinct from Malice) does not need
to be adjacent, they can settle the malicious HTLC further downstream to the
same effect at the cost of more routing fees.

## Patch

This vulnerability was patched in lnd v0.11.0-beta, by properly isolating the
preimage database from the invoice database according to the HTLC's next_hop
field in commit cf739f3f [3] of PR 4157 [4]. The isolation ensures that we can
only claim forwarded HTLCs as a result of learning the preimage from an outgoing
HTLC. It also fixes the privacy leak by not revealing invoice preimages unless
the node is the final destination.

Due to the complexities involved in describing vulnerabilities over textual
mediums, the full nature of the issue wasn’t fully understood until after
v0.10.0-beta had been released. Additionally, the covert fix contained in the
v0.11.0-beta release was pushed back due to a concurrent investigation into
network instabilities resulting in unexpected channel closures.

Note, although the above patch fixes the issue, this issue could have also been
avoided by having receivers require payment secrets (BOLT 11 `s` field) since
the attackers would be unable to guess the payment secret. However, left as
optional, the attacker can always downgrade to using malicious HTLCs that omit
the payment secret.

For some time we have debated flipping the switch on requiring payment secrets
across the three major implementations. This vulnerability is further evidence
to the additional safety and privacy benefits. Now almost a year since the
initial deployment of payment secrets in lnd, the upcoming v0.12.0-beta release
of lnd is likely to make payment secrets required by default. We would welcome
other implementations to do the same.

## Timeline

04/19/2020 - Initial report from Antoine Riard
04/29/2020 - lnd v0.10.0-beta released
07/07/2020 - PR 4157 merged into master
08/20/2020 - lnd v0.11.0-beta released
10/08/2020 - Partial Disclosure sent to lightning-dev and lnd mailing list [1]
10/20/2020 - Full Disclosure sent to lightning-dev and lnd mailing list

## References

[1] https://lists.linuxfoundation.org/pipermail/lightning-dev/2020-October/002819.html
[2] https://github.com/lightningnetwork/lnd/blob/9f32942a90bcd91cc37a4a9c6c2fb454f534a65d/invoices/update.go#L229
[3] https://github.com/lightningnetwork/lnd/pull/4157/commits/cf739f3f87fdcb28ab45dfd48e3d18adf26e45b3
[4] https://github.com/lightningnetwork/lnd/pull/4157
[5] https://gist.github.com/ariard/6bdeb995565d1cc292753e1ee4ae402d

A big thank you to Antoine for the responsible disclosure and for helping to
make lnd more safu. More information can be found in Antoine’s disclosure [5].

Conner Fromknecht



More information about the Lightning-dev mailing list