Files
amethyst/commons
Claude 8ce0edeb2c fix(nwc): verify response author against expected wallet-service pubkey
The previous commit dropped `authors` and `#p` from the relay subscription
filter to match Primal's interop shape. Without those, the relay will
deliver any signed kind-23195 event that carries our request id in `#e`,
so an attacker who can observe the request on the relay could forge a
"response" with their own keypair: Amethyst would happily derive a shared
secret from `event.pubKey` (the attacker), decrypt the payload, and
display attacker-controlled balance/transaction data. Even worse,
`paymentTracker.onResponseReceived` removed the pending entry on first
match — so the legitimate wallet reply that followed was silently dropped.

Move the author check from the relay layer into NwcPaymentTracker:

  - `registerRequest` now requires the expected wallet-service pubkey
    (read from the request's `p` tag). LocalCache extracts it during
    `consume(LnZapPaymentRequestEvent)` and refuses to register if the
    request has no `p` tag.
  - `onResponseReceived` takes the response author and returns a sealed
    MatchResult of NoMatch / WrongAuthor / Matched. A WrongAuthor result
    leaves the pending entry in the map so the legitimate response can
    still resolve it.
  - Android LocalCache and DesktopLocalCache both adopt the new API and
    log a warning on suspected spoof attempts.

End-to-end the response is still encrypted under the per-connection shared
secret, so this is a second layer of defence rather than the only one,
but matching the author keeps a forged kind-23195 from consuming the
pending slot and DoSing the legitimate reply.
2026-05-21 21:30:16 +00:00
..