Hi,

Posting an update to this thread, as we are inching closer to an
implementation in lnd that handles this scenario.

I put up a proposed PR today that attempts to solve this in a
backwards compatible manner:
https://github.com/lightningnetwork/lnd/pull/4795

The gist is that in every state we check that the "worst case fee
leak" is at most the channel reserve. The idea is that there should be
no incentive to perform the attack as described, as the cheating party
will gain at most the channel reserve, but at the same time lose its
channel reserve.

Since this makes small channels unusable at high fee rates (the leaked
fee would exceed the channel reserve for just a few, even a single
HTLC) we also clamp the maximum update_fee we'll send at 10 sat/b (a
configurable value). As an example a 1,000,000 sat channel with a 1%
channel reserve would have space for 6 HTLCs at this fee rate.

> Completely adhering to the bring-your-own-fee model for HTLC-txn sounds 
> better as it splits more fairly fees burden between channel participants.

I totally agree that this sounds like the best solution! AFAICT this
would require a (simple) spec change, but would definitely be a big
win and a simple implementation change when we are doing BYOF on the
HTLC transactions anyway :)

- Johan

On Mon, Sep 14, 2020 at 1:30 AM Antoine Riard <antoine.ri...@gmail.com> wrote:
>
> Hi Johan,
>
> > I would be open to patching the spec to disallow update_fee for anchor
> > channels, but maybe we can just add a warning and discourage it.
>
> My initial thinking was just to restrain it for the commitment-level only.
>
> Completely adhering to the bring-your-own-fee model for HTLC-txn sounds 
> better as it splits more fairly fees burden between channel participants. The 
> initiator won't have to pay for the remote's HTLC-txn, especially in periods 
> of high-congestion. A participant shouldn't have to bear the cost of the 
> counterparty choosing to go onchain, as it's mostly a client security 
> parameter ("how many blocks it will take me to confirm ?")  or an economic 
> decision ("is this HTLC worthy to claim/expire ?").
>
> One could argue it's increasing the blockspace footprint as you will use one 
> more pair of input-output but if you're paying the feerate that's lawful 
> usage.
>
> Antoine
>
> Le ven. 11 sept. 2020 à 04:15, Johan Torås Halseth <joha...@gmail.com> a 
> écrit :
>>
>> Hi,
>>
>> Very good observation, most definitely not a type of attack I forseen!
>>
>> Luckily, it was the plan to phase out update_fee all along, in favor
>> of only accepting the minimum relay fee (zero fee if/when package
>> relay is a reality). If I understand the scenario correctly, that
>> should mitigate this attack completely, as the attacker cannot impact
>> the intended miner fees on the HTLCs, and could only siphon off the
>> minimal miner fee if anything at all.
>>
>> I would be open to patching the spec to disallow update_fee for anchor
>> channels, but maybe we can just add a warning and discourage it.
>>
>> Johan
>>
>>
>> On Thu, Sep 10, 2020 at 8:13 PM Olaoluwa Osuntokun <laol...@gmail.com> wrote:
>> >
>> > Hi Antoine,
>> >
>> > Great findings!
>> >
>> > I think an even simpler mitigation is just for the non-initiator to 
>> > _reject_
>> > update_fee proposals that are "unreasonable". The non-initiator can run a
>> > "fee leak calculation" to compute the worst-case leakage of fees in the
>> > revocation case. This can be done to day without any significant updates to
>> > implementations, and some implementations may already be doing this.
>> >
>> > One issue is that we don't have a way to do a "soft reject" of an 
>> > update_fee
>> > as is. However, depending on the implementations, it may be possible to 
>> > just
>> > reconnect and issue a co-op close if there're no HTLCs on the commitment
>> > transaction.
>> >
>> > As you mentioned by setting proper values for max allowed htlcs, max in
>> > flight, reserve, etc, nodes are able to quantify this fee leak risk ahead 
>> > of
>> > time, and set reasonable parameters based on their security model. One 
>> > issue
>> > is that these values are set in stone rn when the channel is opened, but
>> > future iterations of dynamic commitments may allow us to update them on the
>> > fly.
>> >
>> > In the mid-term, implementations can start to phase out usage of update_fee
>> > by setting a minimal commitment fee when the channel is first opened, then
>> > relying on CPFP to bump up the commitment and any HTLCs if needed. This
>> > discovery might very well hasten the demise of update_fee in the protocol
>> > all together as well.  I don't think we need to depend entirely on a
>> > theoretical package relay Bitcoin p2p upgrade assuming implementations are
>> > willing to make an assumption that say 20 sat/byte or w/e has a good chance
>> > of widespread propagation into mempools.
>> >
>> > From the perspective of channel safety, and variations of attacks like
>> > "flood & loot", imo it's absolutely critical that nodes are able to update
>> > the fees on their second-level HTLC transactions. As this is where the real
>> > danger lies: if nodes aren't able to get 2nd level HTLCs in the chain in
>> > time, then the incoming HTLC expiry will expire, creating a race condition
>> > across both commitments which can potentially cascade.
>> >
>> > In lnd today, anchors is still behind a build flag, but we plan to enable
>> > it by default for our upcoming 0.12 release. The blockers on our end were 
>> > to
>> > add support for towers, and add basic deadline aware bumping, both of which
>> > are currently on track. We'll now also look into setting clamps on the
>> > receiver end to just not accept unreasonable values for the fee rate of a
>> > commitment, as this ends up eating into the true HTLC values for both 
>> > sides.
>> >
>> > -- Laolu
>> >
>> >
>> > On Thu, Sep 10, 2020 at 9:28 AM Antoine Riard <antoine.ri...@gmail.com> 
>> > wrote:
>> >>
>> >> Hi,
>> >>
>> >> In this post, I would like to expose a potential vulnerability introduced 
>> >> by the recent anchor output spec update related to the new usage of 
>> >> SIGHASH_SINGLE for HTLC transactions. This new malleability combined with 
>> >> the currently deployed mechanism of `update_fee` is likely harmful for 
>> >> funds safety.
>> >>
>> >> This has been previously shared with deployed implementations devs, as 
>> >> anchor channels are flagged as experimental it's better to discuss and 
>> >> solve this publicly. That said, if you're currently running experimental 
>> >> anchor channels with non-trusted parties on mainnet, you might prefer to 
>> >> close them.
>> >>
>> >> # SIGHASH_SINGLE and `update_fee` (skip it if you're familiar)
>> >>
>> >> First, let's get started by a quick reminder of the data set committed by 
>> >> signature digest algorithm of Segwit transactions (BIP 143):
>> >> * nVersion
>> >> * hashPrevouts
>> >> * hashSequence
>> >> * outpoint
>> >> * scriptCode of the input
>> >> * value of the output spent by this input
>> >> * nSequence of the input
>> >> * hashOutputs
>> >> * nLocktime
>> >> * sighash type of the signature
>> >>
>> >> Anchor output switched the sighash type from SIGHASH_ALL to 
>> >> SIGHASH_SINGLE | SIGHASH_ANYONECANPAY for HTLC signatures sent to your 
>> >> counterparty. Thus it can spend non-cooperatively its HTLC outputs on its 
>> >> commitment transactions. I.e when Alice broadcasts her commitment 
>> >> transaction, every Bob's signatures on Alice's HTLC-Success/Timeout 
>> >> transactions are now flagging the new sighash type.
>> >>
>> >> Thus `hashPrevouts`, `hashSequence` (ANYONECANPAY) and `hashOutputs` 
>> >> (SINGLE) aren't committed anymore. SINGLE only enforces commitment to the 
>> >> output scriptpubkey/amount at the same index that
>> >> the spending input. Alice is free to attach additional inputs/outputs to 
>> >> her HTLC transaction. This change is aiming to let a single-party bump 
>> >> the feerate of 2nd-stage HTLC transactions in case of mempool-congestion, 
>> >> without counterparty cooperation and thus make HTLC funds safer.
>> >>
>> >> The attached outputs are _not_ encumbered by a revokeable redeemscript 
>> >> for a potential punishment.
>> >>
>> >> That said, anchor ouput spec didn't change disable the current fee 
>> >> mechanism already covering HTLC transactions. Pre/post-anchor channels 
>> >> are negotiating a feerate through `update_fee` exchange, initiated by the 
>> >> channel funder. This `update_fee` can be rejected by the receiver if it's 
>> >> deemed unreasonable compared to your local fee estimator view, but as of 
>> >> today implementations are pretty liberal in their acceptance, admitting a 
>> >> divergence from a scale of 1 to no-bound at all.
>> >>
>> >> This negotiated feerate (`feerate_per_kw`) is used by channel 
>> >> participants to compute effective fees which have to be deduced either 
>> >> from the funder balance output for commitment transactions or from HTLC 
>> >> output value for HTLC transactions.
>> >>
>> >> # The Vulnerability : a Penalty Escape Vector
>> >>
>> >> By increasing the feerate thanks to `update_fee`, a malicious party can 
>> >> inflate fees committed on HTLC input/output pairs and redirect this 
>> >> inflated fee to a single-controlled output attached to these malleable 
>> >> pairs. This won't be punishable by an honest party in case of revoked 
>> >> state broadcast and thus enable to partially escape the penalty.
>> >>
>> >> As an example, Alice and Bob have a 100_000 sats channel. 
>> >> `feerate_per_kw` is 10000 sats.
>> >>
>> >> At state N, Alice balance is all on her side. She announces 10 outgoing 
>> >> HTLCs of value 7000 sats.
>> >>
>> >> As Commitment tx weight with 10 outputs is 2844 (post-anchor), the 
>> >> absolute fee committed is 28440 sats.
>> >>
>> >> As HTLC-timeout weight is 666 (post-anchor), the absolute fee committed 
>> >> is of 6660 sat, the HTLC tx output as counter-signed by Bob is of 340 
>> >> sat. This absolute fee aims to pay the miner fee in case Alice needs to 
>> >> timeout HTLC onchain.
>> >>
>> >> Her remaining balance is 1560 sat, above both dust_limit_satoshi and the 
>> >> channel reserve as constrained by Bob (likely 1%).
>> >>
>> >> Alice waits for HTLCs to expire and advances state to N+1. Then she 
>> >> empties her balance minus reserve by sending a HTLC relayed by Bob either 
>> >> to a colluding channel on the rest of network or back to an onchain 
>> >> address thanks to a swap service.
>> >>
>> >> At state N+2, Alice finalizes HTLC-timeout of state N by capturing almost 
>> >> all of the absolute fee to a new P2WPKH output only controlled by her. 
>> >> She broadcasts the revoked commitment tx N and burns 28440 sats in 
>> >> commitment fee.
>> >>
>> >> Her balance of 1560 sats is punished by Bob's justice transaction.
>> >>
>> >> After confirmation and thus maturing of the CSV of 1 on her HTLC output 
>> >> Alice broadcasts her 10 HTLC-timeout sending back to her 6660 sat - 660 
>> >> to pay a low-fee. Bob punishes the 10 HTLC-timeout outputs of 340 sats.
>> >>
>> >> Alice gain =  99_000 (swap spend) + 66_660 (HTLCs escape) - 1560 
>> >> (commitment balance punishment) - 28440 (commitment fee) - 660*10 (HTLCs 
>> >> fees) - 340*10 (HTLCs output) = 125600 sats.
>> >>
>> >> Alice's gain is superior at channel value as it has been partially 
>> >> double-spend by bypassing the revocation punishment.
>> >>
>> >> # Limitations of Attacker Success
>> >>
>> >> A first limitation of attack success which can be point of is the fact 
>> >> that post-anchor HTLC outputs are CSV'ed by 1, which means in theory a 
>> >> honest party can punish this output before the malicious spend them with 
>> >> the revoked HTLC txn. In practice a malicious party can attach a branch 
>> >> of descendants to its anchor output and that way only allowing one more 
>> >> mempool victim's transaction on the revoked commitment. The victim must 
>> >> spend all outputs at once or otherwise they're going to obstrucate each 
>> >> other at mempool acceptance.
>> >>
>> >> Secondly, other limitations  are the per-implementation channel policy 
>> >> `max_accepted_htlcs`, `max_htlc_value_in_flight`, `channel_reserve` and 
>> >> acceptance bound of `update_fee`. A quick look at default policies, even 
>> >> if they vary between deploy implementations, let it think there is room 
>> >> to escape a substantial part of channel value.
>> >>
>> >> Lastly, after the revoked commitment transaction is confirmed, both 
>> >> attacker and victim are in a feerate race to confirm either a justice 
>> >> transaction or a malicious HTLC-timeout. As fee estimator logic of the 
>> >> victim's implementation is a public piece of knowledge, it shouldn't be 
>> >> hard for the attacker to know the range of the first fee bid and override 
>> >> it by a bit to confirm it before the victim RBF at next block. Currently, 
>> >> not all implementations have RBF of justice transactions.
>> >>
>> >> As of today, if anchor output is deployed and given how LN 
>> >> implementations are managing fees/rebroadcast of onchain transactions, 
>> >> the chance of attack success sounds high in my opinion.
>> >>
>> >> # Countermeasures
>> >>
>> >> Channel policies could be tighter, like bounded further down 
>> >> `max_accepted_htlcs` or restraining acceptance of `update_fee`. For the 
>> >> latter, it's pretty hard as a) fee estimators diverge on mempool views b) 
>> >> an attacker can craft escape HTLC-txn in a period of high-fee and 
>> >> patiently waits a low-fee period to launch the exploitation.
>> >>
>> >> Justice transactions can adopt a scorched earth approach binding their 
>> >> feerate to the max to increase odds of winning the feerate race and thus 
>> >> deter attackers. But this sounds like introducing a griefing attack 
>> >> vector. Your counterparty can burn more of your lawful balance in fees 
>> >> than you'll punish its revoked balance.
>> >>
>> >> A workable option would be to patch current anchor spec to remove 
>> >> `feerate_per_kw` appliance on 2nd-stage transactions, maybe just 
>> >> committing a minimal relay fee.
>> >>
>> >> Thoughts of further countermeasures ?
>> >>
>> >> I think the vulnerability described is mostly right but please point any 
>> >> missing details.
>> >>
>> >> Cheers,
>> >>
>> >> Antoine
>> >> _______________________________________________
>> >> Lightning-dev mailing list
>> >> Lightning-dev@lists.linuxfoundation.org
>> >> https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev
>> >
>> > _______________________________________________
>> > Lightning-dev mailing list
>> > Lightning-dev@lists.linuxfoundation.org
>> > https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev
_______________________________________________
Lightning-dev mailing list
Lightning-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev

Reply via email to