Traefik's ACME TLS-ALPN fast path lacks timeouts and close on handshake stall
Description
Traefik is an HTTP reverse proxy and load balancer. Prior to 2.11.35 and 3.6.7, there is a potential vulnerability in Traefik ACME TLS certificates' automatic generation: the ACME TLS-ALPN fast path can allow unauthenticated clients to tie up go routines and file descriptors indefinitely when the ACME TLS challenge is enabled. A malicious client can open many connections, send a minimal ClientHello with acme-tls/1, then stop responding, leading to denial of service of the entry point. The vulnerability is fixed in 2.11.35 and 3.6.7.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/traefik/traefik/v3Go | < 3.6.7 | 3.6.7 |
github.com/traefik/traefik/v2Go | < 2.11.35 | 2.11.35 |
Affected products
1Patches
1e9f3089e9045Add timeout to ACME-TLS/1 challenge handshake
2 files changed · +70 −1
pkg/server/router/tcp/router.go+12 −1 modified@@ -3,6 +3,7 @@ package tcp import ( "bufio" "bytes" + "context" "crypto/tls" "errors" "io" @@ -206,7 +207,17 @@ func (r *Router) acmeTLSALPNHandler() tcp.Handler { } return tcp.HandlerFunc(func(conn tcp.WriteCloser) { - _ = tls.Server(conn, r.httpsTLSConfig).Handshake() + tlsConn := tls.Server(conn, r.httpsTLSConfig) + defer tlsConn.Close() + + // This avoids stale connections when validating the ACME challenge, + // as we expect a validation request to complete in a short period of time. + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + + if err := tlsConn.HandshakeContext(ctx); err != nil { + log.FromContext(ctx).WithError(err).Debug("Error during ACME-TLS/1 handshake") + } }) }
pkg/server/router/tcp/router_test.go+58 −0 modified@@ -679,6 +679,64 @@ func Test_Routing(t *testing.T) { } } +func Test_Router_acmeTLSALPNHandlerTimeout(t *testing.T) { + router, err := NewRouter() + require.NoError(t, err) + + router.httpsTLSConfig = &tls.Config{} + + listener, err := net.Listen("tcp", "127.0.0.1:0") + require.NoError(t, err) + + acceptCh := make(chan struct{}, 1) + go func() { + close(acceptCh) + + conn, err := listener.Accept() + require.NoError(t, err) + + defer listener.Close() + + router.acmeTLSALPNHandler(). + ServeTCP(conn.(*net.TCPConn)) + }() + + <-acceptCh + + conn, err := net.DialTimeout("tcp", listener.Addr().String(), 2*time.Second) + require.NoError(t, err) + + // This is a minimal truncated Client Hello message + // to simulate a hanging connection during TLS handshake. + clientHello := []byte{ + // TLS Record Header + 0x16, // Content Type: Handshake + 0x03, 0x01, // Version: TLS 1.0 (for compatibility) + 0x00, 0x50, // Length: 80 bytes + } + + _, err = conn.Write(clientHello) + require.NoError(t, err) + + errCh := make(chan error, 1) + go func() { + // This will return an EOF as the acmeTLSALPNHandler will close the connection + // after a timeout during the TLS handshake. + b := make([]byte, 256) + _, err = conn.Read(b) + + errCh <- err + }() + + select { + case err := <-errCh: + assert.ErrorIs(t, err, io.EOF) + + case <-time.After(3 * time.Second): + t.Fatal("Error: Timeout waiting for acmeTLSALPNHandler to close the connection") + } +} + // routerTCPCatchAll configures a TCP CatchAll No TLS - HostSNI(`*`) router. func routerTCPCatchAll(conf *runtime.Configuration) { conf.TCPRouters["tcp-catchall"] = &runtime.TCPRouterInfo{
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-cwjm-3f7h-9hwqghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-22045ghsaADVISORY
- github.com/traefik/traefik/commit/e9f3089e9045812bcf1b410a9d40568917b26c3dghsax_refsource_MISCWEB
- github.com/traefik/traefik/releases/tag/v2.11.35ghsax_refsource_MISCWEB
- github.com/traefik/traefik/releases/tag/v3.6.7ghsax_refsource_MISCWEB
- github.com/traefik/traefik/security/advisories/GHSA-cwjm-3f7h-9hwqghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.