CVE-2026-65959: Vitess Missing Authorization On Vttablet /debug/vrlog Vulnerability

MODERATE
Advisory Identifier: GHSA-mhc4-g3wh-cw7m
CVSS 5.3
CWE-862
Published
Advisory Summary

CVE-2026-65959 is a MODERATE (CVSS 5.3) missing authorization on vttablet /debug/vrlog vulnerability (CWE-862: Missing Authorization) affecting Vitess libraries in the Go ecosystem. The issue involves missing authorization on vttablet /debug/vrlog exposes live vreplication sql data. Remediation is available in the latest vendor maintenance releases.

CVE-2026-65959 at a Glance

CVE Identifier CVE-2026-65959
GHSA Identifier GHSA-mhc4-g3wh-cw7m
Severity MODERATE
CVSS v3.1 Base Score 5.3
CWE Classification CWE-862: Missing Authorization
Affected Product Vitess
Package Ecosystem Go
Published Date
Last Updated

Security Impact

CVSS: 5.3

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N).

Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required None (PR:N)
User Interaction None (UI:N)
Scope Unchanged (S:U)
Confidentiality Low (C:L)
Integrity None (I:N)
Availability None (A:N)

How to Fix CVE-2026-65959

To remediate this vulnerability, upgrade all affected Vitess dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

vitess.io/vitess fixed: Latest secure release
Upgrade vitess.io/vitess to Latest secure release
vitess.io/vitess fixed: Latest secure release
Upgrade vitess.io/vitess to Latest secure release
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

inspect dependencies for vitess.io/vitess

How to Check if You Are Affected

To determine whether your application is affected by CVE-2026-65959, inspect your project dependencies for Vitess:

inspect dependencies for vitess.io/vitess

Analyze the terminal output to locate any version of Vitess in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than the patched release), your application is affected.

Note: Verify declared build manifests and deployed runtime container environments.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-862: Missing Authorization, where the product does not perform an authorization check when an actor attempts to access a resource or perform an action. In Vitess, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

## Vulnerability Details **File**: `go/vt/vttablet/tabletmanager/vreplication/vrlog.go` ### Summary `vttablet`'s `/debug/vrlog` HTTP endpoint streams live VReplication event data — including the literal SQL DML statements being replicated by MoveTables, Reshard, Materialize, and "vitess"-strategy Online DDL workflows — with no authorization check at all. Every comparable "debugging" HTTP endpoint in vttablet/vtgate (querylogz, queryz, txlogz, livequeryz, schemaz, debugenv, hotrows, tablet_plans, query_stats, query_rules) calls `acl.CheckAccessHTTP(r, acl.DEBUGGING)` before serving data, so that the cluster operator's configured `--security-policy` (e.g. `deny-all`, `read-only`, or a custom plugin) is actually honored. `vrlog.go` is the one exception: it has zero references to the `acl` package. ### Root Cause `addHttpEndpoint()` registers `/debug/vrlog` via `servenv.HTTPHandleFunc`, and `vrlogStatsHandler()` immediately starts streaming subscribed `VrLogStats` events to the response writer without first calling `acl.CheckAccessHTTP(r, acl.DEBUGGING)`, unlike every sibling handler in the same family (see e.g. `go/vt/vttablet/tabletserver/querylogz.go`'s `querylogzHandler`, which calls the check first). The data streamed is sensitive: `go/vt/vttablet/tabletmanager/vreplication/vplayer.go` calls `NewVrLogStats(...).Send(sql)` / `.Send(event.Statement)` for every row change and statement event flowing through a VReplication stream (vplayer.go:339, 700, 771, 785) — i.e. the literal SQL (including bound data values) being copied/replicated by MoveTables, Reshard, Materialize, and Online DDL. ### Attack Scenario 1. A cluster operator configures `--security-policy=deny-all` (or `read-only`, or a custom policy) specifically to lock down debugging/admin HTTP endpoints on vttablet, relying on this being uniformly enforced. 2. An attacker who can reach the vttablet debug HTTP port (common in Kubernetes/Prometheus-scraping deployments where this port is exposed beyond localhost) — but who does NOT have the `DEBUGGING`/admin role the policy requires — sends `GET /debug/vrlog`. 3. Every other debug endpoint correctly returns `403 Forbidden`. `/debug/vrlog` returns `200 OK` and streams live VReplication event data, including raw SQL DML statements containing application data values, for as long as the attacker keeps the connection open (bounded by `timeout`/`limit` query params, repeatable). ### Impact Confidentiality impact: disclosure of live replicated application data (potentially including PII or other sensitive column values) to an unauthorized actor, bypassing an access control the operator explicitly configured. No write/modify capability; this is a read-only information-disclosure / access-control-bypass issue, scoped to the vttablet debug HTTP listener. ### Vulnerable Code ```go // go/vt/vttablet/tabletmanager/vreplication/vrlog.go func addHttpEndpoint() { servenv.HTTPHandleFunc("/debug/vrlog", func(w http.ResponseWriter, r *http.Request) { ch := vrLogStatsLogger.Subscribe("vrlogstats") defer vrLogStatsLogger.Unsubscribe(ch) vrlogStatsHandler(ch, w, r) }) } func vrlogStatsHandler(ch chan *VrLogStats, w http.ResponseWriter, r *http.Request) { timeout, limit := parseTimeoutLimitParams(r) // no acl.CheckAccessHTTP(r, acl.DEBUGGING) call anywhere in this file ... ``` ### Recommended Fix ```go import "vitess.io/vitess/go/acl" func vrlogStatsHandler(ch chan *VrLogStats, w http.ResponseWriter, r *http.Request) { if err := acl.CheckAccessHTTP(r, acl.DEBUGGING); err != nil { acl.SendError(w, err) return } timeout, limit := parseTimeoutLimitParams(r) ... ``` This mirrors the exact pattern already used by `querylogz.go`, `queryz.go`, `txlogz.go`, `livequeryz.go`, `schemaz.go`, `debugenv.go`, and `tx_serializer.go` (hotrows) in the same codebase. ### Verification Built v24.0.1 from source and wrote a standalone Go test that: (1) activates the real `deny-all` security policy via `acl.RegisterFlags`, (2) registers `/debug/vrlog` via the real, unmodified `vreplication.NewVrLogStats(...)` call path (the same one `vplayer.go` uses for live replication traffic), (3) serves the real `servenv` HTTP mux on a loopback listener, and (4) issues a real `GET /debug/vrlog` while emitting a simulated replicated statement. Result: ``` acl.CheckAccessHTTP(DEBUGGING) under deny-all => err=not allowed: deny-all security-policy enforced GET /debug/vrlog under deny-all => status=200 body="ROWCHANGE Event\tINSERT INTO secret_table (ssn) VALUES ('leaked-via-vrlog')\t2026-06-22T11:01:55\t147101\n" ``` The identical ACL check that protects every sibling endpoint correctly rejected the request, while `/debug/vrlog` returned 200 and streamed the simulated sensitive content — confirming the bypass against real, unmodified v24.0.1 code. Also confirmed via the GitHub Contents API that `vrlog.go` has zero references to the `acl` package on `main`, `release-23.0`, and `release-22.0` as well, so all currently supported release lines appear affected.

CVE-2026-65959 Affected Vitess Versions

2 component(s)
Product / Package Ecosystem Affected Versions Fixed Version
vitess.io/vitess
Go
≥ 0.24.0-rc1
≤ 0.24.2
vitess.io/vitess
Go
≤ 0.23.6

References

Frequently Asked Questions

What is CVE-2026-65959?
CVE-2026-65959 is a security vulnerability in Vitess involving Missing authorization on vttablet /debug/vrlog exposes live VReplication SQL data under CWE-862: Missing Authorization.
Which Vitess versions are affected?
Affected versions include releases prior to current release patches across affected packages: vitess.io/vitess.
What version fixes CVE-2026-65959?
Upgrading to current release patches (or the latest patched release for your respective branch) resolves the vulnerability.
Is vitess.io/vitess affected?
Yes, vitess.io/vitess is affected in releases prior to Latest secure release. Upgrade your dependency to Latest secure release or later.
What is the CVSS score of CVE-2026-65959?
CVE-2026-65959 has a CVSS v3.1 base score of 5.3 (MODERATE) with vector string CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N.
What CWE is associated with CVE-2026-65959?
CVE-2026-65959 is classified under CWE-862: Missing Authorization (The product does not perform an authorization check when an actor attempts to access a resource or perform an action.).
How can I check Go dependencies for CVE-2026-65959?
Run the dependency tree command: 'inspect dependencies for vitess.io/vitess'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-mhc4-g3wh-cw7m",
  "modified" : "2026-09-02T15:26:56Z",
  "published" : "2026-08-18T20:50:54Z",
  "aliases" : [ "CVE-2026-65959" ],
  "summary" : "Vitess: Missing authorization on vttablet /debug/vrlog exposes live VReplication SQL data",
  "details" : "## Vulnerability Details\n\n**File**: `go/vt/vttablet/tabletmanager/vreplication/vrlog.go`\n\n### Summary\n`vttablet`'s `/debug/vrlog` HTTP endpoint streams live VReplication event data — including the literal SQL DML statements being replicated by MoveTables, Reshard, Materialize, and \"vitess\"-strategy Online DDL workflows — with no authorization check at all. Every comparable \"debugging\" HTTP endpoint in vttablet/vtgate (querylogz, queryz, txlogz, livequeryz, schemaz, debugenv, hotrows, tablet_plans, query_stats, query_rules) calls `acl.CheckAccessHTTP(r, acl.DEBUGGING)` before serving data, so that the cluster operator's configured `--security-policy` (e.g. `deny-all`, `read-only`, or a custom plugin) is actually honored. `vrlog.go` is the one exception: it has zero references to the `acl` package.\n\n### Root Cause\n`addHttpEndpoint()` registers `/debug/vrlog` via `servenv.HTTPHandleFunc`, and `vrlogStatsHandler()` immediately starts streaming subscribed `VrLogStats` events to the response writer without first calling `acl.CheckAccessHTTP(r, acl.DEBUGGING)`, unlike every sibling handler in the same family (see e.g. `go/vt/vttablet/tabletserver/querylogz.go`'s `querylogzHandler`, which calls the check first).\n\nThe data streamed is sensitive: `go/vt/vttablet/tabletmanager/vreplication/vplayer.go` calls `NewVrLogStats(...).Send(sql)` / `.Send(event.Statement)` for every row change and statement event flowing through a VReplication stream (vplayer.go:339, 700, 771, 785) — i.e. the literal SQL (including bound data values) being copied/replicated by MoveTables, Reshard, Materialize, and Online DDL.\n\n### Attack Scenario\n1. A cluster operator configures `--security-policy=deny-all` (or `read-only`, or a custom policy) specifically to lock down debugging/admin HTTP endpoints on vttablet, relying on this being uniformly enforced.\n2. An attacker who can reach the vttablet debug HTTP port (common in Kubernetes/Prometheus-scraping deployments where this port is exposed beyond localhost) — but who does NOT have the `DEBUGGING`/admin role the policy requires — sends `GET /debug/vrlog`.\n3. Every other debug endpoint correctly returns `403 Forbidden`. `/debug/vrlog` returns `200 OK` and streams live VReplication event data, including raw SQL DML statements containing application data values, for as long as the attacker keeps the connection open (bounded by `timeout`/`limit` query params, repeatable).\n\n### Impact\nConfidentiality impact: disclosure of live replicated application data (potentially including PII or other sensitive column values) to an unauthorized actor, bypassing an access control the operator explicitly configured. No write/modify capability; this is a read-only information-disclosure / access-control-bypass issue, scoped to the vttablet debug HTTP listener.\n\n### Vulnerable Code\n```go\n// go/vt/vttablet/tabletmanager/vreplication/vrlog.go\nfunc addHttpEndpoint() {\n\tservenv.HTTPHandleFunc(\"/debug/vrlog\", func(w http.ResponseWriter, r *http.Request) {\n\t\tch := vrLogStatsLogger.Subscribe(\"vrlogstats\")\n\t\tdefer vrLogStatsLogger.Unsubscribe(ch)\n\t\tvrlogStatsHandler(ch, w, r)\n\t})\n}\n\nfunc vrlogStatsHandler(ch chan *VrLogStats, w http.ResponseWriter, r *http.Request) {\n\ttimeout, limit := parseTimeoutLimitParams(r)\n\t// no acl.CheckAccessHTTP(r, acl.DEBUGGING) call anywhere in this file\n\t...\n```\n\n### Recommended Fix\n```go\nimport \"vitess.io/vitess/go/acl\"\n\nfunc vrlogStatsHandler(ch chan *VrLogStats, w http.ResponseWriter, r *http.Request) {\n\tif err := acl.CheckAccessHTTP(r, acl.DEBUGGING); err != nil {\n\t\tacl.SendError(w, err)\n\t\treturn\n\t}\n\ttimeout, limit := parseTimeoutLimitParams(r)\n\t...\n```\nThis mirrors the exact pattern already used by `querylogz.go`, `queryz.go`, `txlogz.go`, `livequeryz.go`, `schemaz.go`, `debugenv.go`, and `tx_serializer.go` (hotrows) in the same codebase.\n\n### Verification\nBuilt v24.0.1 from source and wrote a standalone Go test that: (1) activates the real `deny-all` security policy via `acl.RegisterFlags`, (2) registers `/debug/vrlog` via the real, unmodified `vreplication.NewVrLogStats(...)` call path (the same one `vplayer.go` uses for live replication traffic), (3) serves the real `servenv` HTTP mux on a loopback listener, and (4) issues a real `GET /debug/vrlog` while emitting a simulated replicated statement.\n\nResult:\n```\nacl.CheckAccessHTTP(DEBUGGING) under deny-all => err=not allowed: deny-all security-policy enforced\nGET /debug/vrlog under deny-all => status=200 body=\"ROWCHANGE Event\\tINSERT INTO secret_table (ssn) VALUES ('leaked-via-vrlog')\\t2026-06-22T11:01:55\\t147101\\n\"\n```\nThe identical ACL check that protects every sibling endpoint correctly rejected the request, while `/debug/vrlog` returned 200 and streamed the simulated sensitive content — confirming the bypass against real, unmodified v24.0.1 code.\n\nAlso confirmed via the GitHub Contents API that `vrlog.go` has zero references to the `acl` package on `main`, `release-23.0`, and `release-22.0` as well, so all currently supported release lines appear affected.",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "Go",
      "name" : "vitess.io/vitess"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0.24.0-rc1"
      }, {
        "last_affected" : "0.24.2"
      } ]
    } ]
  }, {
    "package" : {
      "ecosystem" : "Go",
      "name" : "vitess.io/vitess"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "last_affected" : "0.23.6"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/vitessio/vitess/security/advisories/GHSA-mhc4-g3wh-cw7m"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-65959"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/vitessio/vitess/pull/20467"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/vitessio/vitess/commit/4c58cd70edc6b03d61cb65842c342ac08341e64f"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/vitessio/vitess/commit/657662e78bde1c82df680e9cc43a686d619f8094"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/vitessio/vitess/commit/d929225a450027406687d27af8dca45620945ceb"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/vitessio/vitess"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-862" ],
    "severity" : "MODERATE",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-08-18T20:50:54Z",
    "nvd_published_at" : "2026-08-18T19:17:00Z"
  }
}