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-2022-23632

The Dot That Killed mTLS: Traefik CVE-2022-23632

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 21, 2026·6 min read·10 visits

Executive Summary (TL;DR)

Traefik versions < 2.6.1 fail to normalize Fully Qualified Domain Names (FQDNs) during TLS configuration lookups. Sending a Host header like 'example.com.' causes Traefik to miss the custom security policy (like mTLS) and revert to the default policy, potentially allowing unauthenticated access.

A logic error in Traefik's TCP router allows attackers to bypass specific TLS configurations—including Mutual TLS (mTLS) requirements—simply by appending a trailing dot to the Host header. This forces the proxy to fall back to the default, often less secure, TLS configuration.

The Hook: The Syntax Sugar of the Internet

In the world of DNS, we often forget that google.com is actually google.com.. That trailing dot represents the root of the DNS hierarchy. Browsers hide it, marketing teams hate it, but to a resolver, it is the absolute truth. It is the Fully Qualified Domain Name (FQDN). Most web servers normalize this automatically, stripping the dot before processing the request to ensure example.com and example.com. are treated as the same entity.

But what happens when a modern, "cloud-native" reverse proxy like Traefik decides to take things literally? You get CVE-2022-23632. This isn't a buffer overflow or a complex heap grooming exercise. It is a fundamental disagreement between how a user types a domain and how Go's map lookups handle strings.

Imagine you have a fortress. The front door is guarded by a bouncer who checks IDs (mTLS). The window, however, just has a sign that says "Default Entry." If you walk up to the bouncer and say "I am here for the Fortress," he checks your ID. If you say "I am here for the Fortress..." (with a dramatic pause/dot), the bouncer gets confused, checks his list, doesn't see an exact string match for the name with the pause, and shrugs: "I guess you go to the Default Entry then." You just walked past the security because of a punctuation mark.

The Flaw: Exact Matches in a Fuzzy World

The vulnerability resides in pkg/server/router/tcp/router.go. Traefik uses a map to store TLS configurations, keyed by the hostname. When a request comes in, Traefik extracts the Host header (or SNI) and looks it up in this map to determine which security settings to apply—cipher suites, min/max TLS versions, and crucially, ClientAuth (mTLS) settings.

The logic was painfully simple: exact string matching. In Go, map["example.com"] is a completely different memory address than map["example.com."]. There was no normalization step. If your configuration defined rules for secure.internal, the map key was secure.internal.

When an attacker sends a request with Host: secure.internal., the router successfully routes the traffic (because the routing logic often handles FQDNs or wildcards differently), but the TLS configuration lookup fails. Instead of rejecting the connection, Traefik's fail-safe mechanism kicks in: it applies the DefaultTLSConfigName. If your default configuration is permissive (which it usually is to support public traffic), the attacker just downgraded the security of that specific connection to the baseline.

The Code: The Smoking Gun

Let's look at the vulnerable function findTLSOptionName. It takes a map of options and the host string. Notice the lack of preprocessing on the host variable.

// Vulnerable Code (simplified)
func findTLSOptionName(tlsOptionsForHost map[string]string, host string) string {
    // Direct map lookup. If host is "example.com.", this returns nil
    tlsOptions, ok := tlsOptionsForHost[host]
    if ok {
        return tlsOptions
    }
    
    // ... (logic to check wildcards omitted) ...
    
    // Fallback to default if no match found
    return traefiktls.DefaultTLSConfigName
}

The fix introduced in version 2.6.1 is a classic "try it both ways" approach. It acknowledges that the input might be an FQDN and tries to normalize it by stripping or adding the dot to find a match.

// Patched Code in v2.6.1
func findTLSOptName(tlsOptionsForHost map[string]string, host string, fqdn bool) string {
    // 1. Try exact match
    tlsOptions, ok := tlsOptionsForHost[host]
    if ok { return tlsOptions }
 
    if !fqdn { return "" }
 
    // 2. Try STRIPPING the trailing dot
    if last := len(host) - 1; last >= 0 && host[last] == '.' {
        tlsOptions, ok = tlsOptionsForHost[host[:last]]
        if ok { return tlsOptions }
        return ""
    }
 
    // 3. Try ADDING a trailing dot
    tlsOptions, ok = tlsOptionsForHost[host+"."]
    if ok { return tlsOptions }
 
    return ""
}

This simple change closes the gap. Now, example.com. will successfully resolve to the config for example.com.

The Exploit: Bypassing mTLS

The most dangerous scenario for this bug is an mTLS bypass. Mutual TLS is often used for internal services, where the server requires the client to present a trusted certificate. This is common in Zero Trust architectures.

The Setup:

  1. Traefik Config: One router for api.secret.corp with strict mTLS required.
  2. Default Config: Standard TLS (no client cert required) for public pages.

The Attack: A standard request gets blocked:

$ curl https://api.secret.corp/admin
> 400 Bad Request (No Client Certificate)

The exploit request adds the dot:

$ curl -k --header "Host: api.secret.corp." https://api.secret.corp/admin

What happens internally:

  1. SNI: The attacker sends api.secret.corp in the ClientHello (standard TLS).
  2. Handshake: Traefik accepts the connection. It looks up the TLS options for api.secret.corp. (from the header/SNI logic depending on setup).
  3. Lookup Fail: It finds no config for the FQDN version.
  4. Fallback: It applies DefaultTLSConfig (no mTLS).
  5. Routing: The HTTP router still matches the host api.secret.corp. to the correct backend service because the routing rules often treat FQDNs leniently or use regex.
  6. Success: The request reaches the backend without a client certificate. If the backend relies solely on Traefik for authentication, the attacker is in.

The Impact: Security Theater

This vulnerability turns robust security configurations into security theater. The impact is technically rated as High (7.4), but functionally, it can be Critical depending on your architecture.

If you rely on Traefik as an Ingress Controller for Kubernetes, and you use it to terminate mTLS for sensitive pods, this bug renders that protection null and void against a trivial manipulation. It also allows attackers to bypass specific cipher suite restrictions. For example, if secure.bank.com requires TLS 1.3, but the default config allows TLS 1.0, an attacker could force a protocol downgrade by using the FQDN trick, potentially opening the door to other cryptographic attacks.

The real kicker? This leaves almost no trace in standard logs other than a slightly weird Host header, which most analysts would ignore as a typo or browser quirk.

The Fix: Upgrade or Normalize

The remediation is straightforward: Upgrade to Traefik v2.6.1. The patch handles the FQDN normalization logic internally, ensuring that host and host. share the same security context.

Emergency Workaround: If you cannot upgrade immediately (perhaps you are stuck on an old vendor fork), you must explicitly define the FQDN in your router rules. If your rule is Host(\example.com`)`, you need to change it to:

rule = "Host(`example.com`) || Host(`example.com.`)"

However, this is tedious and error-prone. The upgrade is the only scalable fix. This serves as a reminder to developers: inputs are messy, humans are creative, and DNS is a ancient beast that will bite you if you don't respect the dot.

Official Patches

TraefikPull Request #8764 fixing the issue

Fix Analysis (1)

Technical Appendix

CVSS Score
7.4/ 10
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N
EPSS Probability
0.56%
Top 32% most exploited

Affected Systems

Traefik v2.0 through v2.6.0Oracle Communications Unified Inventory Management 7.5.0

Affected Versions Detail

Product
Affected Versions
Fixed Version
Traefik
Traefik Labs
< 2.6.12.6.1
AttributeDetail
CWE IDCWE-295
Attack VectorNetwork
CVSS v3.17.4 (High)
EPSS Score0.00557 (Low)
ImpactSecurity Bypass (mTLS/TLS Options)
Exploit StatusPoC Available

MITRE ATT&CK Mapping

T1557Adversary-in-the-Middle
Credential Access
T1090Proxy
Command and Control
CWE-295
Improper Certificate Validation

Improper Certificate Validation

Known Exploits & Detection

GitHubUnit test case demonstrating the mismatch behavior

Vulnerability Timeline

Fix committed to master
2022-02-14
CVE Published & Traefik v2.6.1 Released
2022-02-17
Oracle releases patch for affected products
2022-07-19

References & Sources

  • [1]GitHub Security Advisory
  • [2]Traefik TLS Documentation

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•CVE-2026-58197
8.8

CVE-2026-58197: Host Escape and Lateral Movement via Insecure Container Network Defaults in ToolHive

A high-severity access control vulnerability in ToolHive CLI before v0.30.1 and ToolHive Studio before v0.38.0 allows local containerized MCP servers to bypass network isolation. This enables malicious workloads to establish TCP/IP connections to administrative and control plane endpoints exposed on the host loopback interface.

Amit Schendel
Amit Schendel
7 views•8 min read
•about 16 hours ago•CVE-2026-63405
5.9

CVE-2026-63405: Insufficient Verification of Data Authenticity in AnyCable Pusher REST API

AnyCable is a real-time communication server. Prior to version 1.6.15, its Pusher-compatible REST API suffered from an authentication bypass vulnerability because it failed to verify that the request body matched the signature-validated body_md5 parameter. This allows attackers to perform replay attacks with modified body contents.

Amit Schendel
Amit Schendel
7 views•5 min read
•about 17 hours ago•CVE-2026-64847
6.8

CVE-2026-64847: Indefinite Denial of Service via Undrained Stderr in AnyIO Process Pool Workers

A denial-of-service vulnerability exists in AnyIO prior to version 4.14.2. Standard error streams of process-pool workers are connected to an operating system pipe that is never drained by the parent process. This allows a worker to fill the pipe buffer and deadlock indefinitely.

Amit Schendel
Amit Schendel
7 views•6 min read
•about 18 hours ago•CVE-2026-63349
7.0

CVE-2026-63349: Privilege Dropping Bypass and Denial of Service in AnyIO Subprocess Module

CVE-2026-63349 is a critical privilege-dropping bypass vulnerability in the AnyIO asynchronous framework (versions 4.14.0 and 4.14.1) on POSIX platforms. Due to a variable assignment typo, supplementary groups specified by the developer are not correctly propagated to the execution backend, resulting in subprocesses retaining the parent process's elevated supplementary group permissions.

Alon Barad
Alon Barad
10 views•5 min read
•about 19 hours ago•CVE-2026-63406
5.9

CVE-2026-63406: Information Disclosure via Insecure Telemetry and Hardcoded Credentials in AnyCable-Go

CVE-2026-63406 is an information disclosure vulnerability in AnyCable-go prior to version 1.6.15. The built-in telemetry client is enabled by default with a hardcoded public authentication token ('secret'). This client digests highly sensitive configuration parameters and command-line arguments, including JWT secrets and RPC secrets, into a stable SHA-256 fingerprint. This fingerprint is sent over public networks, exposing those administrative secrets to offline dictionary and brute-force attacks if intercepted.

Alon Barad
Alon Barad
7 views•5 min read
•about 20 hours ago•CVE-2026-84992
6.1

CVE-2026-84992: Cross-Site Scripting (XSS) via Fenced Code Block Parsing in md-editor-v3

CVE-2026-84992 is a Cross-Site Scripting (XSS) vulnerability affecting md-editor-v3 before version 6.5.4. It occurs because the fenced-code block language parser directly interpolates unescaped language metadata into unquoted HTML attributes inside the custom rendering callback. This bypasses the built-in XSSPlugin which runs during the parsing phase, before rendering.

Amit Schendel
Amit Schendel
9 views•6 min read