LND: gossip_timestamp_filter DoS

LND: gossip_timestamp_filter DoS

LND 0.18.2 and below are vulnerable to a denial-of-service (DoS) attack involving repeated gossip requests for the full Lightning Network graph. The attack is trivial to execute and can cause LND to run out of memory (OOM) and crash or hang. You can protect your node by updating to at least LND 0.18.3 or by setting ignore-historical-gossip-filters=true in your node configuration.

Background

To send payments successfully across the Lightning Network, a node generally needs to have an accurate view of the Lightning Network graph. Lightning nodes maintain a local copy of the network graph that they continuously update as they receive channel and node updates from their peers via a gossip protocol.

New nodes and nodes that have been offline for a while need a way to bootstrap their local copy of the network graph. A common way this is done is to send a gossip_timestamp_filter message to some of the node’s peers, requesting that they share all gossip messages they have that are newer than a certain timestamp. Nodes that cooperate with the message will load the requested gossip from their databases and send them to the requesting peer.

The Vulnerability

By default, LND cooperates with all gossip_timestamp_filter requests. Prior to v0.18.3, LND’s logic to respond to these requests looks like this:

func RespondGossipFilter(filter *GossipTimestampFilter) {
  gossipMsgs := loadGossipFromDatabase(filter)

  go func() {
    for msg := range gossipMsgs {
      sendToPeerSynchronously(msg)
    }
  }
}

LND loads all requested messages into memory at the same time, and then sends them one by one to the peer, pausing after each send until the peer acknowledges receiving the message. The peer can specify any filter, including one that requests all historical gossip messages to be sent to them, and LND will happily comply with the request. As a result, LND can load potentially hundreds of thousands of messages into memory for each request. And since LND has no limit on the number of concurrent requests it will handle, memory usage can get out of hand quickly.

The DoS Attack

Exploiting this vulnerability to DoS attack a victim is easy. An attacker simply needs to:

  1. Send lots of gossip_timestamp_filter messages to the victim, setting the timestamp to 0 to request the full graph.
  2. Keep the connection with the victim open by periodically sending pings and slowly ACKing incoming messages.

This causes LND’s memory consumption to grow over time, until an OOM occurs.

Experiment

I carried out this DoS attack against an LND node with 8 GB of RAM and 2 GB of swap. After a few minutes, the node exhausted its RAM and started using swap, and LND’s performance slowed to a crawl. After about 2 hours, LND exhausted the swap as well and the operating system killed the LND process.

The Mitigation

LND 0.18.3 added a global semaphore to limit the number of concurrent gossip_timestamp_filter requests that LND will cooperate with. While this doesn’t fix LND’s excessive memory usage per request, it does limit the global impact on memory usage, which is enough to protect against this DoS attack.

Discovery

This vulnerability was discovered while looking at how LND handles various peer messages.

Timeline

  • 2023-07-13: Vulnerability reported to the LND security mailing list.
  • 2023-12-11: Failed attempt at a stealth mitigation, which could be bypassed by using multiple node IDs when carrying out the attack.
  • 2023-12-11: Emailed the security mailing list again, explaining the problem with the attempted mitigation.
  • 2024-08-27: Proper mitigation merged.
  • 2024-09-12: LND 0.18.3 released containing the fix.
  • 2025-07-22: Gijs gives the OK to disclose publicly.
  • 2025-07-22: Public disclosure.

Prevention

This vulnerability has existed ever since gossip filtering was added to LND in 2018. The pull request that added the feature contained over 5k lines of new code and received only minor review feedback. It seems that no one was thinking adversarially about the new code at that time, and apparently no one has re-evaluated the code since then.

While it’s understandable that developers were more focused on building features and shipping quickly in the early days of the Lightning Network, I think it is long overdue that a shift is made to more careful development. Engineering with security in mind is slower and more difficult, but in the long run it pays dividends in the form of greater user trust and disasters avoided.

Takeaways

  • Update to at least LND 0.18.3 or set ignore-historical-gossip-filters=true to protect your node.
  • More investment in Lightning security is needed.

Matt Morehouse

Matt Morehouse
Software engineer working to improve the security and stability of the Bitcoin Lightning Network.

LND's Deadline-Aware Budget Sweeper

Discussion about the benefits of LND's new approach to fee bumping commitment and HTLC transactions. Continue reading

LND: Excessive Failback Exploit

Published on March 04, 2025

LDK: Duplicate HTLC Force Close Griefing

Published on January 29, 2025