Skip to content

fix: F-2026-18136 | [Dual Defense] Unauthenticated Peers Can Exhaust TSS Stream Quota and Stall Outbound Signing - #301

Merged
Aman035 merged 1 commit into
audit-fixesfrom
F-2026-18136
Aug 12, 2026
Merged

fix: F-2026-18136 | [Dual Defense] Unauthenticated Peers Can Exhaust TSS Stream Quota and Stall Outbound Signing#301
Aman035 merged 1 commit into
audit-fixesfrom
F-2026-18136

Conversation

@Aman035

@Aman035 Aman035 commented Aug 10, 2026

Copy link
Copy Markdown
Member

F-2026-18136

The root cause - inbound TSS streams admitted from any libp2p identity and blocking in readFramed before any peer check

Remediations applied

# Auditor recommendation Status What we did
1 Validator-aware ConnectionGater rejecting unknown peer IDs at secured-connection admission ✅ Done validatorGater.InterceptSecured rejects inbound connections whose authenticated peer ID is not an eligible UV. Attacker is dropped before protocol negotiation.
2 Maintain allowed set from authoritative UV snapshot, incl. lifecycle transitions ✅ Done Coordinator.IsKnownPeer reads validatorsSnapshot(), refreshed from Push Chain every poll (~10s). Status-strict: admits ACTIVE, PENDING_JOIN, PENDING_LEAVE (the union that can participate in any TSS protocol); rejects INACTIVE/UNSPECIFIED/nil-lifecycle. Fails closed on empty/stale cache.
3 Recheck RemotePeer() at start of handleStream, reset unauthorized ✅ Done handleStream re-checks the authorizer first and stream.Reset()s if unauthorized — covers a validator removed from the set while an old connection is still open.
6 Bound concurrent stream reads (semaphore/worker pool) ✅ Done 64-slot semaphore (readSem) gates readFramed; over-limit streams are reset immediately, so slow peers can't pin unbounded goroutines.
8 Regression tests: unknown peers can't consume capacity; validator traffic survives a flood ✅ Done Network tests: unknown peer never reaches the handler; an authorized validator's message still delivers during an 8-peer unauthenticated flood; a revoked peer's new streams are reset on an already-open connection. Coordinator tests cover the status filter, unknown/nil/stale cases, and bootstrap.

Remediations deliberately skipped (with rationale)

  • Custom resource manager reserving validator capacity - Not implemented. libp2p's default resource manager already bounds handshakes/streams, and with the gater dropping unknown peers at secured-connection admission (before protocol negotiation or any framed read), a Sybil attacker only ever spends our TLS/noise handshakes - never TSS stream quota or read goroutines. A reservation layer adds tuning surface for marginal gain. Can revisit if load testing shows handshake-level pressure. Since the validators no. is itself small, this is not needed
  • Per-IP limits on connections/streams/incomplete handshakes - Not implemented as a distinct control. Peer-ID gating already rejects non-validators before they consume stream resources; the residual surface is bare TLS handshakes, bounded by the default rcmgr. Per-IP caps would harden the handshake tier specifically.
  • Delivery-ack + retry for ACK/BEGIN/DKLS step - Not added at the message layer, because equivalent recovery already exists at the event layer: sessions expire via the expiry sweeper and retry after SessionExpiryBlockDelay. A lost ACK delays a session, it doesn't strand it. Adding message-level ACK/retry would duplicate that guarantee.

@Aman035 Aman035 changed the title fix: gate TSS libp2p inbound to eligible universal validators F-2026-18136: gate TSS libp2p inbound to eligible universal validators Aug 12, 2026
@Aman035 Aman035 changed the title F-2026-18136: gate TSS libp2p inbound to eligible universal validators fix: F-2026-18136 | [Dual Defense] Unauthenticated Peers Can Exhaust TSS Stream Quota and Stall Outbound Signing Aug 12, 2026
@Aman035
Aman035 merged commit 4a1096d into audit-fixes Aug 12, 2026
9 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant