pull down to refresh

Welcome to Latest Strikes, your (lately bi-) weekly report of the latest Lightning-related news. As in the past few issues, this edition is heavily focused on software security releases. We've got releases from all major implementations to cover, exploits, and more.

rust-lightning Release & Candidate

https://git.rust-bitcoin.org/lightningdevkit/rust-lightning/releases/tag/v0.3-rc1 of rust-lightning was released 2 weeks ago, improving on splicing, Bolt12 and more. A few personal picks:

  • pending splices can now be RBF'd, and it is now possible to splice funds in and out in a single transaction;
  • Bolt12 payments can now receive arbitrary metadata, and support for Bolt12 Payer Proofs was added;
  • anchor channels can now drop the requirement for a remote (trusted) party to hold a reserve in the channel, which is especially useful in the LSP context as it allows the user to spend their whole balance.

Note that this release brings some incompatibilities. Notably:

  • v0.3-rc1 is a breaking change for Bolt11 invoices carrying metadata, because now the invoice's secret commits to those. Existing metadata-bearing invoices will be invalidated, and invoices generated under v0.3-rc1 would be invalidated by a downgrade;
  • outbound payments still awaiting a Bolt12 invoice response won't complete across the upgrade;
  • Bolt12 refunds issued before the update will not be claimable after updating.

See the full backwards compatibility report before upgrading.

A week later, the maintenance release 0.2.6 was also released, bringing bug and security fixes to the stable 0.2 line:

  • a fix to a bug that could lead to a node crashing on restart in some circumstances. When a channel is closed while it has not seen any activity and doesn't hold any funds for the node, the node archives the monitoring of this channel right away, since there's nothing else to do about it. However, this early archiving could lead to a state where the ChannelManager component still holds an entry for this channel, but with no corresponding monitoring, leading to a crash on restart (the manager refuses to deserialize);
  • a fix in rust-lightning's splice negotiation protocol, where a counterparty initiating a splice could inflate their apparent contribution to the fee[1], passing checks while actually paying a lower fee than agreed. Crucially, this lowers the effective transaction fee, potentially increasing confirmation time, while letting the initiator pocket the difference in their own output;
  • a fix to another bug where the ChannelManager refuses to deserialize on restart, this time caused by a bogus HTLC (immediately rejected but leaving an empty entry) followed by a valid and successfully forwarded HTLC with the same hash. This can be triggered remotely by anyone routing a payment through your node, and leads to the same failure on restart as the above "early channel archiving" bug.

Outside of these releases, a fix was also merged for a stale buffer bug that could lead to a channel force close after a splice, if the peers disconnect at a specific point during the splice protocol. This bug was found through fuzzing.

Core Lightning Embargo Ending & Heads Up

There have been reports early this week of users getting funds stolen on (even the latest version of) Core Lightning when using the dual-funding feature. Yesterday, Core Lightning's official X account issued a Security Advisory, urging operators to disable all experimental features immediately while investigations continue. Such experimental features include dual-funding, some LSP-related features, and more. While incredibly wide, this advice appears to confirm the substantiality of the above reports, so Core Lightning operators should exercise extreme caution. When possible, the --offline flag remains an option to stop peer traffic while still watching the chain.

On another note, the embargo on the latest Core Lightning release was lifted last Friday (September 11th), meaning we now have access to the source code for this release. If you have not yet done so, I strongly encourage you to update to this latest version (v26.06.7) of Core Lightning.

An analysis of the changelog shows a few predominant topics. While the summary below is definitely not exhaustive, it covers some of the fixes that appear especially important to me.

Revoked Commitment Disguised As Mutual Close (scaryyyy)

When a peer opens a channel with no upfront shutdown script, they can specify this script later, at close time. It was possible for an attacker to cause a Core Lightning node to mis-classify a force close with a revoked commitment as a mutual close, by using the to_local script of a past commitment as the shutdown script. Failing to detect the force close, the CLN node would not broadcast a justice transaction, allowing the peer to steal funds.

On-chain Preimage vs. Unfinished Failure

Given 2 HTLCs with the same payment hash, a peer can fulfill one and fail the other, stop before either removal is final (old state revoked), and claim both HTLCs on-chain with the preimage. In that case, the specification adequately states that the preimage path wins, but Core Lightning would skip the "pending fail" HTLC. For a routing node, this could lead to loss of funds, since the outgoing HTLC is settled on-chain but the incoming one is never settled and eventually times out.

On-chain Feerate Fixes

As we all know, Lightning remains strongly anchored to on-chain Bitcoin. While this is what confers Lightning its very strong self-custodial guarantees, it also comes with the drawback of exposing Lightning nodes to a range of bugs and attacks stemming from badly managed on-chain feerates.

  • In mutual closes, a CLN node could apparently be "talked into" paying a higher feerate than it would have under a unilateral close. The unilateral close feerate, fed from the estimator with current on-chain conditions, now acts as an upper bound for the negotiation of the mutual close feerate;
  • In splicing and dual-funding, a CLN node would accept any feerate from the peer, even if outside of the node's boundaries, which weren't properly piped there. A counterparty could therefore have the CLN node store an absurdly high feerate, or on the other side agree to a feerate as low as 0 (for dual-funding, splicing already has a lower bound), causing untimely confirmation or no valid RBF path. In the case of Core Lightning accepting absurdly high feerates in splicing/dual-funding, this could render RBF impossible (due to Bolt 2 "25/24 rule"), and could even in some cases lead to a node-wide crash loop on startup due to a u32 overflow.

Remote DoS Fixes

Speaking of crashes, this security release also addresses a number of remotely triggerable DoS vectors, on top of the "feerate poisoning" one mentioned above.

  • a node hostname crafted to be over 248 bytes, advertised through gossip, could crash the connectd subdaemon when attempting to connect to the corresponding node, crashing the whole node;
  • a specifically crafted onion message could crash the offers plugin, resulting in a wider crash of the whole node;
  • peers could have as many simultaneous dual-funded (v2) channel openings in progress as they wanted, which could exhaust a Core Lightning node's resources with a very high number of in-flight channel openings;
  • an especially large unauthenticated request to a clnrest endpoint with a bad rune would crash the node with a segfault. This of course only affects nodes running clnrest, with the corresponding port open;
  • some deeply nested JSON could exhaust the C stack and crash the process parsing the offending JSON. For example, commando parses peer-supplied JSON before checking the rune, so any connected peer could crash the plugin and the node.

LND Release

Version 0.21.3 of LND is out, identical to the release candidate we covered 2 weeks ago. On top of what we already covered there, notable changes are:

  • the fix to a bug that could lead channels to end up in a limbo state if during a mutual close negotiation a peer disconnected before the close transaction was finalized;
  • the fix to a bug where the channel counterparty spending an HTLC output could be treated as the node's own success transaction, passing a non-existent output to the sweeper, potentially poisoning sweep batches[2];
  • a new RPC enabling the creation of on-chain sub-wallets with spending capabilities inside the same node, allowing a single wallet to be split into smaller pockets that each control their own outputs. This new feature is experimental, and funds held in these sub-wallets cannot be recovered with only the seed phrase.

Eclair Release

I'd like to mention en passant that ACINQ published a security release for Eclair last Monday. Since this new version was released only 2 days ago, it belongs to next week's newsletter, but I wanted to let you know so you can update as soon as possible. Per ACINQ's release notes, the developers "highly recommend upgrading, as some of these issues can be exploited by malicious nodes".

Electrum Release

Version 4.8.2 of the Electrum wallet was released, and it's a security release. It includes several Lightning-related fixes, notably:

  • payments sent are no longer marked as failed when the receiver can still claim them because there are still some pending HTLCs;
  • multiple fixes to payment forwarding, which is still experimental in Electrum;
  • for some wallets (those using non-deterministic Lightning keys and anchor channels), the channel backup missed some critical key material, making recovery of funds in Lightning channels impossible because they lacked the key to sweep the to_remote output after the peer force-closed the channel. This is now fixed.

Alby Hub Vulnerability For Old Versions

A vulnerability affecting old versions (more than a year!) of Alby Hub appear to have been exploited in the wild. We don't have the full details yet, but it seems the vulnerability could "allow an attacker who could reach the Hub's management API to gain unauthorized access and send funds", if the Hub is publicly accessible from the internet.

Please, in the name of Satoshi, update your software, especially if it holds keys to Bitcoin funds. The affected versions here are v1.7.0 to v1.18.5 (prior to August 2025), and version 1.19.0 (August 2025) or newer are unaffected.

Swiss Bitcoin Pay Vulnerability & Hack

While doing a generalized review of Bitcoin wallets available on app stores, BlueWallet CTO Igor (aka overtorment) found a critical vulnerability in Swiss Bitcoin Pay (SBP), an app that lets merchants receive on-chain and Lightning payments without having to manage a node. On-chain payments are directly sent to the merchant's wallet in self-custody, and Lightning payments are sent to SBP's Lightning node and automatically withdrawn to the merchant's on-chain wallet periodically (e.g. every 24 hours). However, as Igor found, the app posted the full BIP39 mnemonic to its API when a user completed wallet signup/login. This has since been fixed, but the extent to which user seeds were exposed remains unclear. If you used SBP before, it is strongly advised to remove funds from the wallet and create a new one.

Shortly after the finding, SBP's systems were also breached, potentially (personal opinion here!) by an actor looking to access the mnemonics if those were stored or logged on SBP's servers. According to SBP's communication, user funds are safe (which I believe includes Lightning funds that were pending automatic dispatch), and "any amounts owed to users will be fully returned". However, attackers "may have accessed customer email addresses, Bitcoin addresses and IBANs, transaction history, and hashed passwords" and it is "not yet clear whether any other information was accessed".

So yeah, this is pretty bad. Once again, if you have funds on an SBP wallet, I encourage you to move them to a new wallet asap.

Zeus Release

Zeus v13.2.1 was released with, you guessed it, its load of security fixes. Especially worth noting are:

  • the bump of the pinned LDK version used in Zeus (for the LDK embedded node) from a December 2025 snapshot to the 0.2 release branch head (v0.2.5). This therefore brings to Zeus all the LDK security fixes released up to v0.2.5 of rust-lightning;
  • a fix to a bug (and potential vulnerability) whereby a user could review a given invoice A and end up paying a different invoice B when clicking "Pay". This could happen when a new invoice (B) was pushed to the wallet while the user had begun reviewing the first invoice (A). While the user initially reviewed invoice A, their validation would trigger the payment of invoice B. This second invoice could have been received in the wallet through any of the available vectors, including "the universal input router for QR, clipboard, deep links, and NFC";
  • when paying an LNURL Pay URL or a Lightning Address, Zeus didn't check that the invoice's description hash matched the metadata supplied by the LNURL server, which could allow a malicious server to display "benign identity metadata" (e.g. what the Zeus user expects for this payment) while the actual invoice paid by the wallet "commits to an unrelated description hash [or requests] an arbitrary amount". This is now fixed.

Zaprite

Zaprite revealed the Zaprite P2P App, with the goal of seamlessly coordinating payments between end users and across wallets. Reminiscent of Zaprite's main merchant payment facilitator product, users begin by connecting one or many of the supported wallets in the app. Someone wishing to pay them can then find them through the app (by username or phone number), pick which wallet they want to send from, and on the receiver's side Zaprite P2P will automatically route the payment to one of the connected wallets[3]. Instead of the sender initiating the payment, the receiver can also create a payment request, where they can specify their preferred wallet for reception. If the sender doesn't have the app, a Zaprite P2P link allows them to pay nonetheless, directly to the receiver's wallet.


That's it for the last 2 weeks. As always, thank you so much for reading this far, and until next week!

  1. They achieve that by disguising the channel's current funding output as one of their own UTXOs added as input to the splicing transaction. The receiving node therefore treats the funds in the UTXO as belonging exclusively to the attacker, whereas they're actually shared funds in the channel.

  2. Because the underlying Bitcoin node rejects the sweep as invalid, since it tries to spend a non-existent output.

  3. There are many ways to handle this, but I guess an algorithm trying to minimize costs and maximize reliability will try to match the sender's wallet if the receiver also has it; and otherwise select the best next wallet on the receiver's side.

3 sats \ 1 reply \ @mkmloom 16h

Interesting newsletter, I'm subscribing!

reply
124 sats \ 0 replies \ @fanis OP 8h

Hey! Thanks a lot, and welcome!

Just a follow-up: did you subscribe yet? I don't see any new subscriber around the time of your comment, and since I run the newsletter stack myself I just want to double check it's not a technical issue on my end. Thanks again!

reply