pull down to refresh

After a month-long interruption, Latest Strikes is back baby!

Welcome to Latest Strikes, your periodic newsletter covering the latest developments in the Lightning ecosystem. Now, I know this is supposed to be a weekly newsletter, and it's been a whole month since the last issue, but remember that time is relative. More seriously, since I've not been wandering near supermassive objects lately, I can't really blame that on relativity. Let's just say I've been taken up by a few other things lately; but now we should be able to get back to a regular, weekly schedule! On the bright side, covering a full month means more context at once, and the ability to draw connections between some events. Today's issue will hence be bigger than usual, but also denser, with less time and space to dedicate to specific topics than I would have if I had covered them in a weekly rhythm. Hopefully this space-time density doesn't bring any relativity quirks to the coming thunder.

Core Lightning's Struggle

The last few weeks have been particularly challenging for the Core Lightning team, with a couple of security releases and several attested exploits, in a race between the good and the bad guys. There are 2 reported instances of bugs that were actively exploited in the wild, leading to theft of funds:

  • a dual-funding RBF bug, exploited before the fix was released;
  • a splice revoked commitment bug, exploited after the fix was released.

Of course, many other bugs were fixed in those last 2 releases (v26.06.8 and v26.06.9), but we'll focus on these two in this issue. Operators are strongly advised to update to v26.06.9 asap.

Dual-funding Bug

When opening a dual-funded channel, if the other party initiated an RBF of the funding transaction after the initial funding transaction confirmed but before they acknowledged the channel as ready, the Core Lightning node would proceed with the RBF and replace the funding transaction ID for this channel with the new one.

When the remote party then sends the channel_ready message, Core Lightning uses the new funding as its basis for things like channel capacity. However, since RBF replacements are mutually exclusive and the initial funding transaction was already confirmed, the new funding can never confirm. If at the RBF stage the other party also added inputs to their "fake" funding transaction, the Core Lightning node considers the channel to be bigger than it actually is, and even worse attributes all this extra capacity to the remote node. By routing payments through the victim's node, the attacker is then able to drain funds that actually exist in the victim's other channels.

This bug was fixed in this commit, shipped in v26.06.8. However, it is crucial to note that upgrading doesn't stop the attack if affected channels already exist on your node. Instead, operators should "suspend" affected channels with close <id> 0 after they've upgraded. This basically puts the channel into "shutdown" mode, but without force-closing it, instead waiting on the peer indefinitely for a mutual close. My understanding is that without a yet to be published recovery procedure, such a cooperative close cannot happen (because the victim's node still points to a non-existent funding transaction), so the above command basically makes the channel inactive, stopping the attacker from being able to steal using the bug, but also keeping the funds stranded[2]. In the meantime, operators should keep their node up and running, and back up the database.

This bug was actively exploited.

Splice Bug

During the splicing of a channel, if the channel was force closed[1] after the splice locked (i.e. came into effect) and at least one revocation cycle happened (feerate update, transaction in the channel, etc.), a Core Lightning node would mistakenly consider the commitment at the time of splicing as the last valid one and use it to force close. Since it's not the last one, this enables the other party to claim all of the channel funds, using their penalty transaction. The only way to (accidentally) prevent this bug would have been a restart between the splice and the force close, which would have cleared from memory the dangling reference to the now expired commitment.

This bug was fixed in commit c65eec3 of v26.06.8, but was sadly exploited after the release on non-upgraded nodes. Note that unlike dual-funding, splicing is not considered experimental any more, and is therefore enabled in Core Lightning by default.

Luckily, there's no Bitcoin company called Third.

On September 19th, an attacker was able to access an admin interface in Blink's systems and use it to change the registered email address and phone number on 35 accounts, log into them as if they were the owner and withdraw funds. This illegitimate access was made possible because these admin controls were accessible over the public internet (not behind a VPN), in conjunction with a couple of blind spots on authentication token issuance and validation. In the end, 24 users were stolen from (the others were protected by 2FA, which was requested to initiate the withdrawals), and all have been made whole. The attackers also accessed data (such as email and phone number) from 3,817 other accounts. For more details, see Blink's very thorough post-mortem.

On October 5th, Second sustained an attack that targeted their Ark server's boarding flow, where the attacker exploited a bug that allowed them to bypass the need for the server's signature at boarding, then exit the Ark with some of Second's liquidity.[3] Analysis from Blink's team revealed that the same attacker is behind both attacks, since they reused the same Lightning node to fund their attack.

Blink has also put up a web page with all the information they were able to gather regarding the attacker's movement of funds, and are offering a bounty to whoever can help in the recovery of stolen funds.

LDK Release

Versions https://git.rust-bitcoin.org/lightningdevkit/rust-lightning/releases/tag/v0.1.13 and 0.2.7 of rust-lightning both packed a fix for 2 fund-theft vulnerabilities and 2 denial-of-service vulnerabilities, on top of the usual amount of other improvements and bug fixes.

  • Conflicting commitment. A malicious node could send a payment to themselves through a channel they share with an LDK node, acknowledge the corresponding channel update, then on reconnect pretend it didn't see it. A vulnerable LDK node would then sign a new commitment, but since the channel state actually advanced, the new commitment is one step in the future, and the LDK node doesn't properly track it. The attacker would then be take this stranded on-chain, wait for it to confirm (unbeknownst to the victim), claim the HTLC off-chain through their downstream node, and also claim the on-chain HTLC in the published commitment once it expires. This allows the attacker to steal the amount of the HTLC. Fixed in 5057.
  • Naive LSP Flow. The Just-in-Time channel flow in the LSP component of rust-lightning blindly trusted the expected_outbound_amount_msat value a payer specified in their onion, and forwarded this amount to the destination without checking that the payer's HTLC matched the amount. This could allow an attacker to steal funds from the LSP by sending to themselves through the JiT channels funded by the LSP. Fixed in 5042.
  • Electrum DoS. When accepting an inbound channel, a malicious party could construct the funding transaction to trigger the query of "a substantial quantity of transactions" from the Electrum server serving as an LDK node's source for on-chain data. Fixed in 4867.
  • Node Crash. The ChannelManager crash on restart that we covered in the previous issue is also included in this release.

Eclair Release

As announced in the last issue, ACINQ published Eclair v0.14.3 on September 14th, a security release whose fixes mostly come from Project Loupe's AI-assisted audit. The release notes don't say much, but the commit messages describe several ways a malicious peer could make an Eclair node lose funds:

  • During a splice where Eclair signs first (e.g. if it doesn't contribute any input), if the peer doesn't send their signature, Eclair would still try to force-close with a commitment that lacked the counterparty's signatures. Since that can't happen, the force-close transaction would remain dangling, with the publisher retrying on and on. A malicious peer could exploit this to grief or steal funds.
  • A peer could propose a closing fee larger than the node's balance, which Eclair would accept, sending its entire balance to miners.
  • A wallet node could set a null CLTV delta in a blinded path, making Eclair open a channel on the fly and lose the HTLC it relayed through it.

Other fixes protect the node against a malicious bitcoind, and a new max-funding-feerate option caps the feerate of both funding and splice transactions.

Matt Morehouse and Erick Cestari also disclosed denial-of-service vulnerabilities fixed in Eclair v0.14.0 and v0.14.1 (here and there). Some of them, like the open_channel race, could make a node run out of memory. If you've upgraded to v0.14.3, you're covered for all of them. If not, upgrading is as usual very strongly advised. As Morehouse pointed out in a comment under Cestari's Delving post, Phoenix users are unaffected by those vulnerabilities because Acinq already patched their own node.

Other Releases

In this new agentic paradigm, it goes without saying that the last month has seen its load of software releases. Since I can't realistically cover them all as extensively as the ones above, here is a bullet list of the releases that caught my eye. If you're running a piece of software in the list, it's likely advisable to upgrade if you haven't done so yet.


That's it for the last month! We should now be able to go back to our weekly schedule, so with untamed hope I tell you, dear reader: until next week!

  1. For example, by a malicious peer aware of the issue. ↩

  2. Note that even with a procedure that points the node back to the correct funding transaction, the Core Lightning node would still lack properly signed commitment transactions and will hence not be able to force close the channel. The attacker holds a revoked commitment transaction, which the victim can penalize should they publish it. The only clean exit hence seems to be a cooperative close with the attacker, once Core Lightning follows the real funding transaction, which the attacker has little reason to agree to since they've already spent their balance and don't have much at stake. ↩

  3. It is important to emphasize here that the attacker was not able to steal any user funds, since those can't be spent by the server itself. ↩

Worth the wait; this was a great read! Thanks for digging into all the exploits.

reply

Thank you for your kind words!

reply

Thank you, I was waiting for your newsletter!

reply

Thank you, and sorry it took so long!

reply

No need to be sorry! I simply wondered if everything was alright and wished you didn't give it up for whatever reason.
My prayer has been listened, look forward to next one.

reply

Great....thanks for sharing

reply
3 sats \ 0 replies \ @Chikasunbeats 15 Oct -22 sats

Great breakdown @fanis! This CL struggle highlights the razor edge Lightning devs walk.
‎
‎Two exploits in the wild for real sats is scary - especially the dual-funding RBF one exploited BEFORE the fix. Shows why running latest version (v26.06.9) isn't optional, it's survival.
‎
‎Makes you appreciate how complex channel state management is. "This little maneuver gonna cost us 51 years" meme is perfect - one small RBF nuance = funds gone.
‎
‎Are most node operators now updated? Any stats on how many still on vulnerable versions?‎
Stay safe out there. Update your nodes!