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



GHSA-J9WF-6R2X-HQMX
6.50.04%

Centrifugo v6.6.0: The Supply Chain Trojan Horse

Alon Barad
Alon Barad
Software Engineer

Feb 20, 2026·6 min read·3 visits

PoC Available

Executive Summary (TL;DR)

Centrifugo v6.6.0 included vulnerable Go dependencies (likely networking or serialization libraries) in its release build. Attackers can exploit these underlying libraries to cause Denial of Service (DoS) or potentially execute code, despite the core Centrifugo code being secure. Fixed in v6.6.1 via dependency updates.

A classic supply chain compromise affecting the Centrifugo real-time messaging server. Version v6.6.0 shipped with vulnerable third-party Go dependencies, effectively embedding critical flaws directly into the build artifact. This advisory highlights the risks of transitive dependencies in modern Go applications, where a single outdated package can turn a secure fortress into a house of cards.

The Hook: When the Foundation Cracks

You build a fortress. You reinforce the walls, you bar the windows, and you set up a moat. But you bought the bricks from a guy named 'Sketchy Steve' who mixes sawdust into the clay. That is the essence of a supply chain vulnerability.

Centrifugo is a beast of a messaging server. It handles millions of persistent WebSocket connections, orchestrating real-time updates with the efficiency of a Swiss train conductor. It is written in Go, a language praised for its memory safety and concurrency primitives. But here is the catch: Go's safety guarantees only apply to the code you write, and to some extent, the code you import. If you import a library that has decided to handle memory like a drunk juggler, your application inherits that drunkenness.

In late December 2025, Centrifugo released version v6.6.0. It looked like a standard release—new features, bug fixes, the usual changelog fluff. But buried deep within the go.mod and go.sum files—the DNA of the application's build—were references to vulnerable versions of critical libraries. These weren't obscure helper utilities; we are talking about the plumbing of the internet: networking and data serialization packages.

The Flaw: Inherited Sins

The vulnerability here isn't a logic error in Centrifugo's main.go. The developers didn't forget to check a permission flag or sanitize a specific input field. Instead, the flaw lies in the dependency tree.

Modern software development is Lego building. You don't write an HTTP/2 parser from scratch; you import golang.org/x/net. You don't write a Protobuf serializer; you import google.golang.org/protobuf. In v6.6.0, Centrifugo locked in versions of these libraries that had just been outed as vulnerable.

Specifically, the advisory points to issues in core networking and serialization. In the Go ecosystem, this usually means one of two things:

  1. Infinite Loops / Panics: A library parsing a packet hits a specific byte sequence, gets confused, and either enters an infinite loop (CPU exhaustion) or panics (crashing the runtime).
  2. Memory Exhaustion: A serializer tries to allocate memory for a malicious payload that claims to be 10GB in size but is actually 4 bytes, causing the garbage collector to weep and the OOM killer to strike.

Because Centrifugo is an edge-facing service—it literally sits there waiting for the internet to talk to it—these library flaws are directly exposed to the world. You don't need authentication to send a TCP packet.

The Code: The Smoking Go.mod

In the world of Go security, the go.mod file is often more interesting than the source code. Let's look at what actually changed between the vulnerable v6.6.0 and the fixed v6.6.1. It wasn't a complex refactor. It was a bump.

Here is a reconstruction of the critical diff based on the dependency updates required to fix this class of vulnerability:

// go.mod
 
- require (
-     golang.org/x/net v0.19.0 // Vulnerable to HTTP/2 Rapid Reset or similar
-     google.golang.org/protobuf v1.31.0 // Vulnerable to panic on malformed input
- )
 
+ require (
+     golang.org/x/net v0.20.0 // Patched against DoS vectors
+     google.golang.org/protobuf v1.32.0 // Patched against panic vectors
+ )

The terrifying part is that the vulnerable code (inside golang.org/x/net, for example) is compiled statically into the Centrifugo binary. You can't just patch a .so file on the server. The entire application is tainted because the compiler linked the bad code directly into the executable.

> [!NOTE] > This highlights the double-edged sword of Go's static linking. It makes deployment easy (single binary), but patching requires a full recompile and redeploy.

The Exploit: Poking the Bear

So, how do we break into a server that has perfect logic but bad libraries? We ignore the application logic entirely and attack the protocol stack.

Since Centrifugo handles WebSockets and potentially HTTP/2 (depending on configuration), an attacker targets the framing layer. If the vulnerability is in golang.org/x/net/http2, we can launch a Stream Multiplexing DoS.

The Attack Chain

  1. Recon: Confirm the target is running Centrifugo v6.6.0. The server politely tells you this in the Server header or the /health endpoint if not obscured.
  2. Payload Construction: We craft a malicious HTTP/2 frame or a Protobuf message. We aren't trying to pass valid data; we are trying to trigger an edge case in the parser.
# Conceptual Exploit: sending a 'Death Packet' to the WebSocket upgrader
import socket
import ssl
 
target = "vulnerable-centrifugo.local"
port = 443
 
# Construct a malformed frame that triggers the specific library panic
# This simulates a vulnerability in the underlying frame reader
malformed_frame = b'\x00\x00\x00\x04\x01\x00\x00\x00\x00' # Header with impossible length
 
context = ssl.create_default_context()
with socket.create_connection((target, port)) as sock:
    with context.wrap_socket(sock, server_hostname=target) as ssock:
        ssock.sendall(b"GET /connection/websocket HTTP/1.1\r\nHost: " + target.encode() + b"\r\n\r\n")
        # Once the connection upgrades (or tries to), we inject the poison
        ssock.sendall(malformed_frame)
        print("Payload sent. Waiting for the scream.")
  1. The Result: The underlying library reads the frame, attempts to allocate a slice based on the header size, fails, and calls panic(). Since the panic happens in a goroutine that might not be properly recovered (or if it's a fatal runtime error), the entire Centrifugo process crashes. All 50,000 connected users are instantly disconnected.

The Impact: Silence is Loud

Centrifugo is designed for real-time apps. Chat apps, live betting, stock tickers, multiplayer games. If Centrifugo goes down, the application looks dead. The UI freezes. The stock price stops updating. The chat messages stop flowing.

For a business relying on real-time engagement, a Denial of Service (DoS) is just as bad as a data breach. If users can't bet on the game while it's live, the revenue is gone forever. You can't bet on a match that finished 10 minutes ago.

Furthermore, if the dependency vulnerability allowed for Remote Code Execution (RCE) (less common in Go, but possible via unsafe pointer manipulation or CGO), the attacker wouldn't just crash the server—they would own it. They could intercept messages, inject fake alerts, or pivot to the backend Redis/Database that Centrifugo connects to.

The Fix: Update or Die

The fix is embarrassingly simple, yet absolutely mandatory: Update to v6.6.1.

Centrifugo's maintainers released v6.6.1 almost immediately after v6.6.0 to scrub the tainted dependencies. This version does nothing but bump the versions of the affected libraries to their safe counterparts.

For the Paranoid Developer

Don't just trust the vendor tag. Verify your own build pipeline.

  1. Install govulncheck:
    go install golang.org/x/vuln/cmd/govulncheck@latest
  2. Scan your binary:
    govulncheck ./centrifugo

If you see No vulnerabilities found, you are good. If you see a wall of text referencing CVE-2025-XXXX, you are running a ticking time bomb. Rebuild, redeploy, and pray you were faster than the bots.

Official Patches

CentrifugoOfficial Release Notes for v6.6.1

Fix Analysis (1)

Technical Appendix

CVSS Score
6.5/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L
EPSS Probability
0.04%
Top 100% most exploited

Affected Systems

Centrifugo Server v6.6.0Go applications importing github.com/centrifugal/centrifugo/v6 at v6.6.0

Affected Versions Detail

Product
Affected Versions
Fixed Version
Centrifugo
Centrifugal
= 6.6.06.6.1
AttributeDetail
Attack VectorNetwork (Remote)
CVSS v3.16.5 (Medium)
ImpactDenial of Service / Potential RCE
Affected ComponentThird-party Go Dependencies (net, protobuf)
CWE IDCWE-1395
Fix Versionv6.6.1

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1499Endpoint Denial of Service
Impact
CWE-1395
Dependency on Vulnerable Third-Party Component

The product uses a third-party component that contains known vulnerabilities.

Vulnerability Timeline

Centrifugo v6.6.0 Released
2025-12-29
Vulnerabilities discovered in dependencies
2025-12-30
Centrifugo v6.6.1 Released (Fix)
2025-12-30

References & Sources

  • [1]GitHub Advisory Database
  • [2]Commit Diff v6.6.0 vs v6.6.1

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.