This is the story of how I almost lost the funds on the lnproxy node 🙈. And how Rene Pickhardt (https://www.rene-pickhardt.de/) saved the day.
Yesterday, on twitter, Rene asked:
How do you handle cltv delay? Do you just encode a large one into the invoice that you give out? Does this mean you have already found a payment flow and locked in htlcs or do you just guess generously? https://nitter.net/renepickhardt/status/1572933510326804481#m
I'm embarrassed to admit that I had thought about the cltv delay, but it seemed complicated, so I decided to stop thinking about it.
Fortunately, Rene's question got me thinking again and I realized that that the service was vulnerable to a simple attack! It would go a little something like this:
Create a hodl invoice:
Wrap the hodl invoice:
Pay the wrapped invoice from another wallet:
The payment will trigger lnproxy to pay the original invoice so that it can learn the preimage.
Check that lnproxy's payment has been accepted by your node and note the
expiry_height to the first payment's
On SBW the expiry is shown on the stuck payment's details,
on lnd you can check the
If the expiry height on the original payment is lower than on the wrapped payment, then wait for the first payment to expire before settling the wrapped payment and profiting:
This vulnerability would have allowed anyone to drain the lnproxy node of funds.
I patched it by extending the
min_final_cltv_expiry on wrapped invoices to ensure I have a few blocks during which to settle the original invoice.