Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Security hardening

Summary. A grab-bag of the defensive choices that don’t fit on one feature page: never auto-paying a request, binding replies to the expected counterparty, hard size ceilings, encrypted keys at rest, replay protection, rate limiting, and routing everything over the mixnet. This page is a map to where each lives.

Motivation

A wallet that accepts messages from strangers and moves money is an attractive target. Goblin’s posture is defense-in-depth: assume any incoming message is hostile, validate before acting, cap everything, and never let the network see more than ciphertext.

The measures

MeasureWhat it preventsWhere
Requests are never auto-paidA stranger draining you with an Invoice-1Ingest policy (decide()SurfaceRequest)
Replies bound to counterparty + pending txA forged Standard-2/Invoice-2 finalizing somethingIngest policy
Size ceilings (64 K / 32 K / 30 K / 256)Memory-blow-up / DoS via huge messagesProtocol constants
Encrypted key at restOffline key theft; password grindingIdentity: NIP-49 ncryptsec, scrypt log_N=16, 0600
Processed-id archive + 30-day TTLReplaying an old payment messageStorage (processed db)
NIP-98 single-use authReplaying a name registration requestName authority
Per-sender rate limitsSpam flooding from one keyNostrService (contact 30/h, unknown 10/h)
Everything over NymIP exposure + timing correlationNym
Reserved names, homograph folding, cooldownImpersonation / squatting on namesName authority
Tag-independent classificationA sender lying about message type via tagsProtocol (classify by parsed slate only)

On the server side, the name authority runs under a hardened systemd sandbox and trusts an X-Real-IP set by its reverse proxy for rate limiting. Because Goblin clients share mixnet exit IPs, server-side abuse controls are tuned to be per-connection / per-account rather than naive per-IP.

References

  • Ingest invariants: goblin/src/nostr/ingest.rs.
  • Protocol ceilings + tag-independence: goblin/src/nostr/protocol.rs.
  • Key at rest: goblin/src/nostr/identity.rs.
  • Replay protection: goblin/src/nostr/store.rs and the server’s NIP-98 handling.
  • Live guards are covered by goblin/tests/{nostr_e2e,replay_check}.rs.