pull down to refresh

@1440000bytes (aka floppy) is at it again with a very interesting discovery in Cashu mints that run nutshell: when paying out of a lightning gateway, it is possible that an attacker could set exorbitant fees which the mint will pay out of its own balance and not charge the mint user for. The result is that the mints funds could be drained, especially if the attacker is requesting the mint pay out to a lightning node the attacker controls.

Cashu mints quote a fee_reserve to the wallet at melt time, and the wallet escrows proofs worth amount + fee_reserve. The mint is then expected to bind that fee_reserve as an upper limit on what its lightning backend will spend.

Nutshell's LNbitsWallet.pay_invoice() ignores the fee_limit_msat argument and sends the bolt11 to the LNbits HTTP API with no cap field. Whatever fee LNbits pays up to its own LNBITS_RESERVE_FEE_PERCENT comes silently out of the mint operator's own funds that swallows negative-overpayment as a logger.error() and returns successfully.
If overpaid_fee is negative i.e. the backend spent more than the wallet escrowed, the mint logs an error and returns an empty list of change. It does not unwind, it does not raise, it does not refuse the spend. The melt is recorded as successful. The proofs are marked spent. The mint operator’s lightning balance is short by exactly fee_paid − fee_provided with no entry in the ledger to recover it.

It looks like nutshell is resolving this by removing LNbits, but mint operators could take the following actions:

Close the gap between the mint’s quoted fee_reserve and the backend’s own cap. Concretely, for operators currently running with LIGHTNING_FEE_PERCENT=0 and LIGHTNING_RESERVE_FEE_MIN=0:
  • Raise LIGHTNING_FEE_PERCENT to at or above the backend’s own cap (for LNbits, that means LIGHTNING_FEE_PERCENT >= LNBITS_RESERVE_FEE_PERCENT, i.e. at least 1.0 with default LNbits). This forces the wallet to escrow at least as much as the backend can ever pay, so overpaid_fee cannot go negative. Wallets may pay slightly more for melts; legitimate users get the excess returned as NUT-08 change.
  • Set LIGHTNING_RESERVE_FEE_MIN to at least 2000 msat so small melts still have a floor (1% of a 100-sat melt is 1 sat = below msat precision).
  • For LNbits backends, also lowering LNBITS_RESERVE_FEE_PERCENT reduces the amount per melt the attacker can drain, but does not close the bug and only raising the mint quote does.
  • Monitor mint.log for Overpaid fee is negative lines. Any occurrence is a fund loss event and indicates active exploitation or an unhealthy backend.

floppy wrote a demo of the exploit which you can find here.

Rug the spaaaaammers!!

reply

Ouch. Ignoring fee_limit_msat basically turns the mint into a fee sponsor for the route.

Curious how many mints were running LNbits with LIGHTNING_FEE_PERCENT=0