<div dir="ltr"><div>Hi y&#39;all, </div><div><br></div><div>I&#39;m not sure how good defenses are on implementations other than lnd, but</div><div>all implementations *should* be keeping a Sphinx reply cache of the past</div><div>shared secrets they know of [1]. If a node comes across an identical shared</div><div>secret of that in the cache, then they should reject that packet. Otherwise,</div><div>it&#39;s possible for an adversary to inject a stale packet back into the</div><div>network in order to observe the propagation of the packet through the</div><div>network. This is referred to as a &quot;replay&quot; attack, and is a de-anonymization</div><div>vector.</div><div><br></div><div>Typically mix nets enforce some sort of session lifetime identifier to allow</div><div>nodes to garbage collect their old shared secrets state, otherwise it grows</div><div>indefinitely. As our messages are actually payments with a clear expiration</div><div>date (the absolute CLTV), we can use this as the lifetime of a payment</div><div>circuit session. The sphinx packet construction allows some optional</div><div>plaintext data to be authenticated along side the packet. In the current</div><div>protocol we use this to bing the payment hash along with the packet. The</div><div>rationale is that in order for me to accept the packet, the attacker must</div><div>use the _same_ payment hash.  If the pre-image has already been revealed,</div><div>then the &quot;victim&quot; can instantly pull the payment, attaching a  cost to a</div><div>replay attempt.</div><div><br></div><div>However, since the CLTV isn&#39;t also authenticated, then it&#39;s possible to</div><div>attempt to inject a new HTLC with a fresher CLTV. If the node isn&#39;t keeping</div><div>around all pre-images, then they might forward this since it passes the</div><div>regular expiry tests. If we instead extend the associated data payload to</div><div>cover the CLTV as well, then this binds the adversary to using the same CLTV</div><div>details. As a result, the &quot;victim&quot; node will reject the HTLC since it has</div><div>already expired. Continuing down this line, if we progressively add more</div><div>payment details, for example the HTLC amount, then this forces the adversary</div><div>to commit the same amount as the original HTLC, potentially making the</div><div>probing vector more expensive (as they&#39;re likely to lose the funds on</div><div>attempt).</div><div><br></div><div>If this were to be deployed, then we can do it by using a new packet version</div><div>in the Sphinx packet. Nodes that come across this new version (signalled by</div><div>a global feature bit) would then know to include the extra information in</div><div>the AD for their MAC check. While we&#39;re at it, we should also actually</div><div>*commit* to the packet version. Right now nodes can swap out the version to</div><div>anything they want, potentially causing another node to reject the packet.</div><div>This should also be added to the AD to ensure the packet can&#39;t be modified</div><div>without another node detecting it.</div><div><br></div><div>Longer term, we may end up with _all_ payment details in the Sphinx packet.</div><div>The only thing outside in the update_add_htlc message would be link level</div><div>details such as the HTLC ID.</div><div><br></div><div>Thoughts?</div><div><br></div><div>[1]: <a href="https://github.com/lightningnetwork/lightning-onion/blob/master/replaylog.go">https://github.com/lightningnetwork/lightning-onion/blob/master/replaylog.go</a></div><div><br></div><div>-- Laolu</div><div><br></div></div>