GCVE Workshop - 22 September 2026 (14:00-18:00), Luxembourg Before The Vulnopticon Conference - Registration

GHSA-C4C3-7FPV-J4Q5

Vulnerability from github – Published: 2026-09-08 18:16 – Updated: 2026-09-08 18:16
VLAI
Summary
Netty: SNI Routing Bypass via Fragmented TLS ClientHello Causing Fallback to Default SslContext
Details

Summary

A fragmented TLS ClientHello whose handshake header spans multiple records makes Netty silently fall back to the default SslContext; where per-SNI selection is the sole mTLS gate, an unauthenticated attacker can bypass the route's mTLS requirement.

Details

In io.netty.handler.ssl.SslClientHelloHandler#decode the guard that should wait for the 4-byte handshake header checks the wrong offset - it ignores the 5-byte record header that precedes it - and therefore never fires:

if (handshakeLength == -1) {
    if (readerIndex + 4 > endOffset) {
        // Need more data to read HandshakeType and handshakeLength (4 bytes)
        return;
    }

When the first record's payload is < 4 bytes, handshakeLength = in.getUnsignedMedium(readerIndex + SslUtils.SSL_RECORD_HEADER_LENGTH + 1); leads to IndexOutOfBoundsException. That is caught by the generic catch (Exception) block, which calls select(ctx, null) - this is the default SslContext. Fallback to default on parse failure is a problem when per-SNI selection is the sole mTLS gate.

Impact

SNI routing bypass. Escalates to an unauthenticated mTLS bypass only when: - mTLS is enforced solely via per-SNI SslContext (clientAuth=REQUIRE) - the default/fallback SslContext is permissive (clientAuth=NONE/OPTIONAL) - no secondary peer-certificate verification exists at the application layer.

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 4.2.16.Final"
      },
      "package": {
        "ecosystem": "Maven",
        "name": "io.netty:netty-handler"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "4.2.0.Final"
            },
            {
              "fixed": "4.2.17.Final"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 4.1.136.Final"
      },
      "package": {
        "ecosystem": "Maven",
        "name": "io.netty:netty-handler"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "4.1.137.Final"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-75595"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-475",
      "CWE-754"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-09-08T18:16:14Z",
    "nvd_published_at": "2026-08-19T21:17:37Z",
    "severity": "CRITICAL"
  },
  "details": "### Summary\nA fragmented TLS ClientHello whose handshake header spans multiple records makes Netty silently fall back to the default SslContext; where per-SNI selection is the sole mTLS gate, an unauthenticated attacker can bypass the route\u0027s mTLS requirement.\n\n### Details\nIn `io.netty.handler.ssl.SslClientHelloHandler#decode` the guard that should wait for the 4-byte handshake header checks the wrong offset - it ignores the 5-byte record header that precedes it - and therefore never fires:\n\n```java\nif (handshakeLength == -1) {\n    if (readerIndex + 4 \u003e endOffset) {\n        // Need more data to read HandshakeType and handshakeLength (4 bytes)\n        return;\n    }\n```\n\nWhen the first record\u0027s payload is \u003c 4 bytes, `handshakeLength = in.getUnsignedMedium(readerIndex + SslUtils.SSL_RECORD_HEADER_LENGTH + 1);` leads to `IndexOutOfBoundsException `. That is caught by the generic `catch (Exception)` block, which calls `select(ctx, null)` - this is the default `SslContext`. Fallback to default on parse failure is a problem when per-SNI selection is the sole mTLS gate.\n\n### Impact\nSNI routing bypass. Escalates to an unauthenticated mTLS bypass only when:\n- mTLS is enforced solely via per-SNI SslContext (clientAuth=REQUIRE)\n- the default/fallback SslContext is permissive (clientAuth=NONE/OPTIONAL)\n- no secondary peer-certificate verification exists at the application layer.",
  "id": "GHSA-c4c3-7fpv-j4q5",
  "modified": "2026-09-08T18:16:14Z",
  "published": "2026-09-08T18:16:14Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/netty/netty/security/advisories/GHSA-c4c3-7fpv-j4q5"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-75595"
    },
    {
      "type": "WEB",
      "url": "https://github.com/netty/netty/pull/17213"
    },
    {
      "type": "WEB",
      "url": "https://github.com/netty/netty/pull/17217"
    },
    {
      "type": "WEB",
      "url": "https://github.com/netty/netty/commit/1b5abc6443b63726c72cdd285af2feb7ddbb8ff7"
    },
    {
      "type": "WEB",
      "url": "https://github.com/netty/netty/commit/9e0519239108a69b7e9bbc5e9182ee139a0d7961"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/netty/netty"
    },
    {
      "type": "WEB",
      "url": "https://github.com/netty/netty/releases/tag/netty-4.1.137.Final"
    },
    {
      "type": "WEB",
      "url": "https://github.com/netty/netty/releases/tag/netty-4.2.17.Final"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Netty: SNI Routing Bypass via Fragmented TLS ClientHello Causing Fallback to Default SslContext"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…

Loading…