mirror of
https://github.com/luxfi/zap.git
synced 2026-07-27 05:54:26 +00:00
fix(handshake): enforce HandshakeTimeoutSec read deadline (pre-auth slowloris)
HandshakeTimeoutSec was defined but referenced nowhere and no SetReadDeadline existed, so a peer could stall the pre-auth handshake indefinitely (goroutine/FD exhaustion). Initiator.Run and Responder.Run now set a read deadline of HandshakeTimeoutSec when conn is a net.Conn, cleared on return; bare io.ReadWriter callers remain responsible for their own timeout. Co-authored-by: Hanzo Dev <dev@hanzo.ai>
This commit is contained in:
co-authored by
Hanzo Dev
parent
048b6c91f5
commit
9b69731086
@@ -9,6 +9,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
@@ -61,6 +62,15 @@ func (i *Initiator) Run(conn io.ReadWriter) (*Session, error) {
|
||||
return nil, errors.New("zap-pq: initiator requires Local with private key")
|
||||
}
|
||||
|
||||
// Bound the whole handshake by HandshakeTimeoutSec so a peer that
|
||||
// connects and then stalls (or dribbles bytes) cannot pin this goroutine
|
||||
// and FD indefinitely. Applies only when conn is a net.Conn; callers
|
||||
// passing a bare io.ReadWriter remain responsible for their own timeout.
|
||||
if nc, ok := conn.(net.Conn); ok {
|
||||
_ = nc.SetReadDeadline(time.Now().Add(HandshakeTimeoutSec * time.Second))
|
||||
defer func() { _ = nc.SetReadDeadline(time.Time{}) }()
|
||||
}
|
||||
|
||||
suite := i.Suite
|
||||
if suite == 0 {
|
||||
suite = SuiteX25519MLKEM
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
@@ -62,6 +63,15 @@ func (rs *Responder) Run(conn io.ReadWriter) (*Session, error) {
|
||||
return nil, errors.New("zap-pq: ReplayCache is required under StrictPQ/FIPS profile")
|
||||
}
|
||||
|
||||
// Bound the whole handshake by HandshakeTimeoutSec so an unauthenticated
|
||||
// peer that connects and then stalls cannot pin this goroutine and FD
|
||||
// indefinitely (pre-auth slowloris). Applies only when conn is a net.Conn;
|
||||
// bare io.ReadWriter callers own their own timeout.
|
||||
if nc, ok := conn.(net.Conn); ok {
|
||||
_ = nc.SetReadDeadline(time.Now().Add(HandshakeTimeoutSec * time.Second))
|
||||
defer func() { _ = nc.SetReadDeadline(time.Time{}) }()
|
||||
}
|
||||
|
||||
r := rs.Rand
|
||||
if r == nil {
|
||||
r = rand.Reader
|
||||
|
||||
Reference in New Issue
Block a user