GHSA-89p3-4642-cr2w: Traefik: TCP readTimeout bypass via STARTTLS on Postgres
ImpactThere is a potential vulnerability in Traefik managing STARTTLS requests.An unauthenticated client can bypass Traefik entrypoint `respondingTimeouts.readTimeout` by sending the 8-byte Postgres SSLRequest (STARTTLS) prelude and then stalling, causing connections to remain open indefinitely, leading to a denial of service.Patcheshttps://github.com/traefik/traefik/releases/tag/v3.6.8For more informationIf you have any questions or comments about this advisory, please [open an issue](https://github.com/traefik/traefik/issues).SummaryA remote, unauthenticated client can bypass Traefik entrypoint `respondingTimeouts.readTimeout` by sending the 8-byte Postgres SSLRequest (STARTTLS) prelude and then stalling, causing connections to remain open indefinitely and enabling file-descriptor and goroutine exhaustion denial of service.This triggers during protocol detection **before routing**, so it is reachable on an entrypoint even when **no Postgres/TCP routers are configured** (the PoC uses only an HTTP router).DetailsTraefik applies per-connection deadlines based on `entryPoints.<name>.transport.respondingTimeouts.readTimeout` to prevent protocol detection and request reads from blocking forever (see `pkg/server/server_entrypoint_tcp.go`, which sets `SetReadDeadline` on accepted connections).However, in the TCP router protocol detection path (`pkg/server/router/tcp/router.go`), when Traefik detects the Postgres STARTTLS signature on a new connection, it executes a fast-path that clears deadlines:detect Postgres SSLRequest (8-byte signature),call `conn.SetDeadline(time.Time{})` (clears all deadlines),then enter the Postgres STARTTLS handler (`servePostgres`).The Postgres handler (`pkg/server/router/tcp/postgres.go`) then blocks waiting for a TLS ClientHello via the same peeking logic used elsewhere (`clientHelloInfo(br)`), but with deadlines removed. An attacker can therefore:connect to any internet-exposed TCP entrypoint,send the Postgres SSLRequest (SSL negotiation request),receive Traefik’s single-byte response (`S`),stop sending any further bytes.Each such connection remains open past the configured `readTimeout` (indefinitely), consuming a goroutine and a file descriptor until Traefik hits process limits._Of note_: CVE-2026-22045 fixed a conceptually-similar DoS where a protocol-specific fast path cleared connection deadlines and then could block in TLS handshake processing, allowing unauthenticated clients to tie up goroutines/FDs indefinitely. This report is the same failure mode, but triggered via the Postgres STARTTLS detection path.Tested versions:`v3.6.7``master` at commit `a4a91344edcdd6276c1b766ca19ee3f0e346480f`PoCPrerequisites:Linux hostPython 3A prebuilt Traefik `v3.6.7` binary. The script below expects the path in the script’s `TRAEFIK_BIN` constant (edit if needed).Execute the script below:ImpactDenial of service. Any internet-exposed entrypoint using the TCP switcher/protocol detection (including "web" HTTP entrypoints) with a `readTimeout` is affected; no Postgres configuration is required. At sufficient concurrency, Traefik can hit process limits (FD exhaustion/goroutine pressure/memory), taking the proxy offline.
CVSS v3.1: 7.5