Public mode

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

Some sources, documents or advisories need attention: 275/275 feeds/APIs · 469/469 docs · 7/9 advisories · checked 06:36 UTC Customize Public modeDiscuss ChangeIntel on Discord

Centrifugo: Client-forgeable headers emulation lets any client spoof headers forwarded to proxy backends

Collected exploitation and prediction evidence

Risk source coverage

CISA KEV is observed exploitation evidence. FIRST EPSS is a dated prediction of exploitation in the next 30 days. Missing scores are unknown. This collector requests predictions only for explicit CVE aliases in the public NuGet archive; Microsoft release views retain their existing prediction scope.

No collected risk observation for these identifiers. This does not establish absence of exploitation or a zero probability.

cve-program · CVE-2026-71485

Published

Centrifugo is an open-source scalable real-time messaging server. Prior to 6.9.0, Centrifugo copies the client-controlled protocol.ConnectRequest.headers map through OnClientConnecting in internal/client/handler.go, ConnectEvent.Headers, and SetEmulatedHeadersToContext. The requestHeaders path in internal/proxy/http.go, the requestMetadata path in internal/proxy/grpc.go, and the Consume path in internal/unigrpc/grpc.go can forward an allowlisted value as a trusted backend header or metadata value. A remote client can spoof a header such as x-trusted-user for connect, refresh, subscribe, publish, RPC, and related proxy calls when the backend relies on that header for authentication or authorization. The unidirectional gRPC transport has no transport-level HTTP header that can override the emulated value. This issue is fixed in version 6.9.0.

Source published
20 Aug 2026 21:01:00 UTC
Source modified
25 Aug 2026 15:23:47 UTC
Observed here
23 Oct 2026 15:48:27 UTC
Source terms
CVE Program Terms of Use

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

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: cve-program · CVE Program Terms of Use. Source text is retained; field grouping and change labels are provided by ChangeIntel.

CVSS 3.1 · 9.1 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N

euvd · EUVD-2026-63649

Published

Centrifugo is an open-source scalable real-time messaging server. Prior to 6.9.0, Centrifugo copies the client-controlled protocol.ConnectRequest.headers map through OnClientConnecting in internal/client/handler.go, ConnectEvent.Headers, and SetEmulatedHeadersToContext. The requestHeaders path in internal/proxy/http.go, the requestMetadata path in internal/proxy/grpc.go, and the Consume path in internal/unigrpc/grpc.go can forward an allowlisted value as a trusted backend header or metadata value. A remote client can spoof a header such as x-trusted-user for connect, refresh, subscribe, publish, RPC, and related proxy calls when the backend relies on that header for authentication or authorization. The unidirectional gRPC transport has no transport-level HTTP header that can override the emulated value. This issue is fixed in version 6.9.0.

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: Aug 20, 2026, 9:01:00 PM

dateUpdated: Aug 25, 2026, 3:23:47 PM

Source published
Aug 20, 2026, 9:01:00 PM (timezone not stated)
Source modified
Aug 25, 2026, 3:23:47 PM (timezone not stated)
Observed here
7 Nov 2026 14:23:27 UTC
Source terms
ENISA EUVD · source terms and attribution apply

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

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: euvd · ENISA EUVD · source terms and attribution apply. Source text is retained; field grouping and change labels are provided by ChangeIntel.

EUVD CVSS 3.1 · 9.1 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N

nvd · CVE-2026-71485

Published

Centrifugo is an open-source scalable real-time messaging server. Prior to 6.9.0, Centrifugo copies the client-controlled protocol.ConnectRequest.headers map through OnClientConnecting in internal/client/handler.go, ConnectEvent.Headers, and SetEmulatedHeadersToContext. The requestHeaders path in internal/proxy/http.go, the requestMetadata path in internal/proxy/grpc.go, and the Consume path in internal/unigrpc/grpc.go can forward an allowlisted value as a trusted backend header or metadata value. A remote client can spoof a header such as x-trusted-user for connect, refresh, subscribe, publish, RPC, and related proxy calls when the backend relies on that header for authentication or authorization. The unidirectional gRPC transport has no transport-level HTTP header that can override the emulated value. This issue is fixed in version 6.9.0.

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: Deferred

Weakness classifications: CWE-290

Original publisher date fields

published: 2026-08-20T21:17:08.707

lastModified: 2026-10-18T20:10:00.110

Source published
20 Aug 2026 21:17:08 UTC
Source modified
18 Oct 2026 20:10:00 UTC
Observed here
25 Oct 2026 15:18:57 UTC
Source terms
NIST NVD usage terms; underlying source attribution retained

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

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: nvd · NIST NVD usage terms; underlying source attribution retained. Source text is retained; field grouping and change labels are provided by ChangeIntel.

CVSS 3.1 · [email protected] · Secondary · 9.1 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N

osv · GHSA-9468-v6mj-fppw

Published

## Vulnerability Details **File**: `internal/client/handler.go` (`OnClientConnecting`), `internal/proxy/http.go` (`requestHeaders`), `internal/proxy/grpc.go` (`requestMetadata`), `internal/unigrpc/grpc.go` (`Consume`) **Line**: handler.go:389,548-552 (`e.Headers` -> `SetEmulatedHeadersToContext`), http.go:131-165 (`requestHeaders`), grpc.go:82-114 (`requestMetadata`), unigrpc/grpc.go:46 (`Headers: req.Headers`) ### Root Cause The `http_headers` / `grpc_metadata` proxy config options are documented as "List of incoming HTTP header names to forward to the proxy backend" / "List of incoming gRPC metadata keys to forward to the proxy backend" -- implying the value originates from the underlying transport connection (e.g. set by a trusted reverse proxy/API gateway in front of Centrifugo). Operators commonly use this to forward identity/trust headers to their own backend for access-control decisions. However, the wire protocol used by every Centrifugo transport (`protocol.ConnectRequest`, field `headers`) includes a `headers` map populated entirely from the connecting client's own message (its JSON `connect` command, or for gRPC, its `ConnectRequest` protobuf field) -- not from real transport-level HTTP headers. Centrifugo copies this client-supplied map verbatim into `ConnectEvent.Headers`, then into an "emulated headers" context value used by every proxy type (connect, refresh, subscribe, publish, rpc, sub_refresh, map_publish, map_remove, shared_poll_refresh) for the entire connection lifetime. Any header name in the operator's allowlist is forwarded to the backend with the client's own chosen value, unless a header of the exact same name also happens to be present on the genuine underlying HTTP request. For the unidirectional gRPC transport specifically there is no HTTP request at all, so there is no possible override -- the client-controlled value always wins. ### Attack Scenario 1. Operator configures a connect proxy with `http_headers: ["x-trusted-user"]` (or any header name their backend uses for caller identity/trust). 2. Attacker connects directly to Centrifugo and sends a connect command containing `"headers": {"x-trusted-user": "<any value>"}`. 3. Centrifugo forwards `X-Trusted-User: <attacker value>` to the backend exactly as if a trusted intermediary had set it. 4. The backend, trusting this header per its own design, grants whatever access/identity it associates with that value. ### Impact Full spoofing of any header value the backend trusts for authentication/authorization, for every proxy call type, for the lifetime of the connection -- up to full account/identity impersonation depending on backend logic. No credentials, JWT, or API key required. ### Vulnerable Code ```go // internal/proxy/http.go func requestHeaders(ctx context.Context, allowedHeaders, allowedMetaKeys []string, staticHeaders map[string]string) http.Header { headers := http.Header{} for k, v := range staticHeaders { headers.Set(k, v) } emulatedHeaders, _ := clientcontext.GetEmulatedHeadersFromContext(ctx) // 100% client-controlled for k, v := range emulatedHeaders { if slices.Contains(allowedHeaders, strings.ToLower(k)) { headers.Set(k, v) // forwarded to backend as a real outgoing HTTP header } } httpHeaders, hasHTTPHeaders := middleware.GetHeadersFromContext(ctx) // real headers, if present for k, vv := range httpHeaders { if slices.Contains(allowedHeaders, strings.ToLower(k)) { headers[k] = vv // only overrides if SAME header name was ALSO on the real request } } ... } ``` ```go // internal/unigrpc/grpc.go -- never goes through HTTP middleware, no competing real-header check at all connectRequest := &protocol.ConnectRequest{ Token: req.Token, Data: req.Data, Name: req.Name, Version: req.Version, Headers: req.Headers, // the gRPC client's own protobuf field } ``` ### Recommended Fix Document explicitly that `http_headers`/`grpc_metadata` values can also be supplied by the connecting client itself via "headers emulation" and are not guaranteed to come from a trusted reverse proxy. Provide a separate allowlist (e.g. `trusted_http_headers`) populated only from genuine transport-level HTTP headers, never from client-supplied `ConnectRequest.headers`, for operators who need an unforgeable header. For uniGRPC, consider disabling `http_headers` forwarding entirely since there is no transport-level header concept to fall back on. ### Verification Dynamically confirmed against the official `centrifugo/centrifugo:v6.8.3` Docker image on BOTH the bidirectional WebSocket transport and the unidirectional gRPC transport, using a minimal backend that logs every header it receives: - WS: connecting with `{"connect": {"headers": {"x-trusted-user": "admin-impersonation-via-headers-emulation"}}}` resulted in the backend receiving `X-Trusted-User: admin-impersonation-via-headers-emulation`, despite no such header existing on the real WebSocket upgrade HTTP request. - uniGRPC: calling the `Consume` RPC with `ConnectRequest(headers={"x-trusted-user": "admin-impersonation-via-unigrpc"})` (zero real gRPC metadata set) resulted in the backend receiving `X-Trusted-User: admin-impersonation-via-unigrpc`. - Control tests (no `headers` field / no metadata) confirmed the header is absent from the backend's request in the baseline case.

Source published
2 Sep 2026 23:41:37 UTC
Source modified
28 Sep 2026 17:11:21 UTC
Observed here
24 Oct 2026 13:19:41 UTC
Source terms
GitHub Advisory Database · CC-BY-4.0

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

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: osv · GitHub Advisory Database · CC-BY-4.0. Source text is retained; field grouping and change labels are provided by ChangeIntel.

CVSS_V3 · CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N

Publisher rating · CRITICAL

osv · GO-2026-6490

Published

Centrifugo: Client-forgeable headers emulation lets any client spoof headers forwarded to proxy backends in github.com/centrifugal/centrifugo

Source published
28 Sep 2026 16:43:40 UTC
Source modified
28 Sep 2026 17:00:16 UTC
Observed here
24 Oct 2026 13:19:41 UTC
Source terms
OSV · upstream source license applies

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

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: osv · OSV · upstream source license applies. Source text is retained; field grouping and change labels are provided by ChangeIntel.

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 9 Nov 06:36 UTC · 275 of 275 readable · 273 fully read · documentation 469/469 current