Article

Identifier Verified
KIND 30023 / Long-form Content
Signature Valid

LNbits Attack - My story


How an LNbits server was used to drain a Lightning node

Summary

An attacker went from a free LNbits account to full control of the
Lightning node behind it in about eight hours. They abused LNbits'
own features and one extension bug to install a malicious extension,
which read the node's LND admin macaroon and tried to close every
channel to the attacker's address and sweep the on-chain wallet.
Fast force-closes by the operator limited the loss to a single channel.

Setup that was attacked

  • LNbits 1.5.4 in Docker, exposed to the internet through a Cloudflare Tunnel
  • Funding source: LND REST on the local network
  • The container mounted the node's whole LND folder, including admin.macaroon
  • Open sign-up and "login by user ID" were both enabled

Attack chain

  1. Accounts. The attacker registered dozens of accounts, many with

admin-style usernames (admin, root, lnbitsadmin, operator, the
operator's own handles) to find real ones, and sent thousands of
password guesses. None got into an admin account, and nothing
rate-limited them.

  1. Probing extensions. They enabled every available extension on

their own accounts and tested each for a way in, including making
the server send requests to its own internal addresses (SSRF).

  1. Reading server files. A flaw in the Paywall extension's

"file" download let a normal user read files inside the LNbits
container, unlocked with a 1-sat payment.

  1. Super user. With what that file read exposed, they made

authenticated super-user requests, even though LNbits blocks
super-user login by user ID alone.

  1. Hosting the payload on the victim. As a normal user they uploaded

a malicious extension zip (labelled as an image) and a fake extension
catalog as LNbits "assets".

  1. Installing it. Using super-user settings, they added the asset's

local URL as a trusted extension catalog and installed the extension
from it.

  1. Taking the node. The extension ran as soon as it was installed:
  • read admin.macaroon from the mounted LND folder
  • listed channels and requested co-op closes to the attacker's address
  • started a loop that tried every 3 minutes to sweep the whole

on-chain balance

  • opened a remote shell endpoint, which the attacker used to fix

bugs in their own sweeper and drop helper scripts

LND rejected the attacker's force-close requests, and their first
sweeper used the wrong API endpoint. The patched sweeper only sent
confirmed funds, and none were confirmed before the container was
stopped.

Signs of compromise to look for

  • An unknown extension in data/extensions/ or data/upgrades/

(this one was named pwnNNNN)

  • lnbits_extensions_manifests containing a URL pointing at

127.0.0.1 or /api/v1/assets/

  • Assets with mismatched types (a .zip or .json stored as image/png)
  • Bursts of new accounts with admin-like names, or mass failed logins
  • Paywalls of type "file" you didn't create
  • Python scripts or JSON logs you don't recognise in the data folder
  • Lots of 1-sat test payments with odd memos
  • Forwarded IPs in reserved ranges (198.51.100.x, 203.0.113.x):

the attacker was forging proxy headers

Why it worked

  1. Public LNbits with open sign-up and login by user ID
  2. An extension bug that let a normal user read files on the server
  3. LNbits' signing secrets stored where that bug could read them
  4. Super users can install code from any catalog (by design)
  5. LNbits held a full-permission admin macaroon. That one fact turned

an LNbits break-in into a node takeover.

  1. No login rate limiting

If you run LNbits, do this now

  • Turn off open sign-up and "user-id-only" login if you don't need them
  • Turn off extensions you don't use, especially ones that fetch URLs

(Paywall file downloads, Watchonly)

  • Never give LNbits admin.macaroon. Bake one with only the permissions

it needs (invoices and Lightning payments; no channel closing, no
on-chain sends) and mount that file alone, not the whole LND folder.

  • Put /admin behind an access gate (Cloudflare Access, VPN, IP allowlist)
  • Rate-limit /api/v1/auth at the proxy
  • Check installed extensions and the manifest list for anything you

didn't add

  • Keep LNbits and its extensions up to date

If you think you're compromised

  1. Stop LNbits and set its restart policy to "no". Malicious extensions

run as soon as they load, and LNbits may reinstall a deleted one at
startup from its database.

  1. Copy the data folder and container logs before changing anything.
  2. On LND: delete the macaroon root keys and generate new macaroons, so

stolen ones stop working.

  1. Force-close channels you don't trust, and move all funds to a new seed.
  2. Don't run the old LNbits install again. Start fresh with a new data

folder and new secrets.

  1. Pay back any custodial balances you hold for other users.
Technical details allowlist: verified allowed
typeaddress
canonical/naddr1qvzqqqr4gupzqcdl0y9jp990kq6ftj0px6k0v9d7plxv9ju4kkk0khmvemlp3vrzqqwkcmnzd968xttpw36xzcmt94khjttnw3hhy7fdv9jrvde4xupjn5c7
allowlistverified allowed
verificationID Verified · Signature Valid
event id54b478e8d14efd5d38988d67e9cd7841f8a112b53f5b87e487fd2fb6629af9fa
author pubkey61bf790b2094afb03495c9e136acf615be0fccc2cb95b5acfb5f6ccefe18b062
kind30023
created_at2026-11-08T19:47:06.000Z (1794167226)
tags count4
content snippet## Summary An attacker went from a free LNbits account to full control of the Lightning node behind it in about eight hours. They abused LNbits' own features and one extension bug to install a malicious extension, which read the node's LND admin macaroon and tried to close every
relays queriedwss://purplepag.es, wss://nos.lol, wss://relay.damus.io, wss://relay.primal.net, wss://relay.nostr.org.tr, wss://relay.emre.xyz