[Lightning-dev] Extending Associated Data in the Sphinx Packet to Cover All Payment Details

Olaoluwa Osuntokun laolu32 at gmail.com
Fri Feb 8 02:57:21 UTC 2019


Hi y'all,

I'm not sure how good defenses are on implementations other than lnd, but
all implementations *should* be keeping a Sphinx reply cache of the past
shared secrets they know of [1]. If a node comes across an identical shared
secret of that in the cache, then they should reject that packet. Otherwise,
it's possible for an adversary to inject a stale packet back into the
network in order to observe the propagation of the packet through the
network. This is referred to as a "replay" attack, and is a de-anonymization
vector.

Typically mix nets enforce some sort of session lifetime identifier to allow
nodes to garbage collect their old shared secrets state, otherwise it grows
indefinitely. As our messages are actually payments with a clear expiration
date (the absolute CLTV), we can use this as the lifetime of a payment
circuit session. The sphinx packet construction allows some optional
plaintext data to be authenticated along side the packet. In the current
protocol we use this to bing the payment hash along with the packet. The
rationale is that in order for me to accept the packet, the attacker must
use the _same_ payment hash.  If the pre-image has already been revealed,
then the "victim" can instantly pull the payment, attaching a  cost to a
replay attempt.

However, since the CLTV isn't also authenticated, then it's possible to
attempt to inject a new HTLC with a fresher CLTV. If the node isn't keeping
around all pre-images, then they might forward this since it passes the
regular expiry tests. If we instead extend the associated data payload to
cover the CLTV as well, then this binds the adversary to using the same CLTV
details. As a result, the "victim" node will reject the HTLC since it has
already expired. Continuing down this line, if we progressively add more
payment details, for example the HTLC amount, then this forces the adversary
to commit the same amount as the original HTLC, potentially making the
probing vector more expensive (as they're likely to lose the funds on
attempt).

If this were to be deployed, then we can do it by using a new packet version
in the Sphinx packet. Nodes that come across this new version (signalled by
a global feature bit) would then know to include the extra information in
the AD for their MAC check. While we're at it, we should also actually
*commit* to the packet version. Right now nodes can swap out the version to
anything they want, potentially causing another node to reject the packet.
This should also be added to the AD to ensure the packet can't be modified
without another node detecting it.

Longer term, we may end up with _all_ payment details in the Sphinx packet.
The only thing outside in the update_add_htlc message would be link level
details such as the HTLC ID.

Thoughts?

[1]:
https://github.com/lightningnetwork/lightning-onion/blob/master/replaylog.go

-- Laolu
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linuxfoundation.org/pipermail/lightning-dev/attachments/20190207/895c8f9c/attachment.html>


More information about the Lightning-dev mailing list