Severity by source
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
Unauthenticated single-request injection (AV:N/AC:L/PR:N/UI:N); confidentiality scored Low since disclosure is largely metric/config-dependent, and Availability Low reflects the documented resource-exhaustion vector.
Primary rating from Vendor (https://github.com/dgraph-io/dgraph).
CVSS VectorVendor: https://github.com/dgraph-io/dgraph
Lifecycle Timeline
1DescriptionCVE.org
Summary
The checkUserPassword GraphQL query in Dgraph is vulnerable to DQL (Dgraph Query Language) injection. User-supplied password values are interpolated directly into a DQL checkpwd() query via fmt.Sprintf without any escaping or parameterization. An attacker can inject a password containing a double-quote character to break out of the DQL string literal and append arbitrary DQL query blocks.
Details
Vulnerable Code Path
The vulnerability exists in the GraphQL-to-DQL query rewriting layer:
query_rewriter.go(~line 364) - Thecheckpwd()DQL function is constructed usingfmt.Sprintf:
fmt.Sprintf(`checkpwd(User.password, "%s")`, password)The raw password string from the GraphQL query input is embedded directly into the DQL query without escaping double quotes or other special characters.
graphquery.go- The constructed query attribute is serialized into the final DQL string viab.WriteString(query.Attr), passing the unsanitized content directly to the Dgraph query engine.
Attack Mechanism
A password value containing a double-quote (") terminates the string literal in the checkpwd() function. Any content after the escaped quote is parsed as additional DQL, allowing the attacker to inject arbitrary query blocks.
Distinction from CVE-2026-41328 and CVE-2026-41327
CVE-2026-41328 and CVE-2026-41327 address DQL injection in edgraph/server.go, where GraphQL mutation inputs (upsert/delete) are embedded unsafely into DQL mutations. Those fixes sanitize the mutation path.
This vulnerability is in a completely different code path - the GraphQL query rewriter (query_rewriter.go → graphquery.go). The checkUserPassword GraphQL query triggers a DQL *query* via checkpwd(), and this query construction was not covered by the patches for CVE-2026-41328/CVE-2026-41327.
PoC
curl -s -X POST http://TARGET:8080/graphql \
-H "Content-Type: application/json" \
-d '{ "query": "query { checkUserPassword(name: \"admin\", password: \"x\\\") { uid } injected(func: has(User.name)) { User.name User.email } dummy(func: eq(x, \\\"x\") { msg } }") { msg } }" }'What to observe:
- The
touched_uidsfield in theextensionssection of the response will be elevated (indicating the injected blocks executed) - Dgraph server logs (
dgraph alphaoutput) will show the injected query blocks being parsed and executed - The response itself may be filtered by the GraphQL layer, but server-side execution is confirmed
Impact
- Data enumeration: Injected query blocks execute server-side and can probe for the existence of predicates, types, and nodes via
touched_uidsmetrics and server logs. - Schema discovery: An attacker can enumerate all predicates and types in the database by injecting
schema {}blocks orhas()queries. - Resource exhaustion: Expensive injected queries (recursive traversals, large aggregations) execute at the DQL layer, consuming server resources regardless of whether results are returned to the attacker.
- Potential data disclosure: Depending on Dgraph configuration (e.g., debug mode, custom extensions), injected query results may leak into the response.
CVSS 3.1: 7.5 High - AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
- Network-accessible via any GraphQL endpoint
- No authentication required (
checkUserPasswordis an unauthenticated query) - Low attack complexity (single crafted HTTP request)
- High confidentiality impact (server-side query execution confirmed, data enumeration possible)
Affected Versions
All versions of Dgraph that include GraphQL support with the @secret directive are affected:
- <= v25.3.3
- Any version where
query_rewriter.goconstructscheckpwd()via string interpolation
Suggested Fix
Escape or parameterize the password value before embedding it in the DQL query. At minimum, double-quote characters in the password must be escaped:
// Before (vulnerable):
fmt.Sprintf(`checkpwd(User.password, "%s")`, password)
// After (escaped):
escaped := strings.ReplaceAll(password, `\`, `\\`)
escaped = strings.ReplaceAll(escaped, `"`, `\"`)
fmt.Sprintf(`checkpwd(User.password, "%s")`, escaped)Ideally, Dgraph should implement parameterized query support for the checkpwd() function to avoid string interpolation entirely, consistent with best practices for injection prevention.
Credit
Kai Aizen (kai.aizen.dev@gmail.com)
AnalysisAI
DQL (Dgraph Query Language) injection in Dgraph's GraphQL-to-DQL query rewriter (versions <= v25.3.3) lets remote unauthenticated attackers inject arbitrary query blocks through the unauthenticated checkUserPassword GraphQL query. User-supplied password values are interpolated into a checkpwd() DQL call via fmt.Sprintf without escaping, so a double-quote breaks out of the string literal and appends attacker-controlled DQL. A working PoC exists (publicly available exploit code exists); the issue is not in CISA KEV and no active exploitation is reported, but server-side execution of injected blocks is confirmed, enabling schema/data enumeration and resource exhaustion.
Technical ContextAI
Dgraph is a distributed, native GraphQL graph database that compiles incoming GraphQL operations into its internal Dgraph Query Language (DQL). The flaw is rooted in CWE-943 (Improper Neutralization of Special Elements in Data Query Logic). In the rewriting layer, query_rewriter.go (~line 364) builds the password check as fmt.Sprintf(checkpwd(User.password, "%s"), password), and graphquery.go later serializes that attribute verbatim via b.WriteString(query.Attr) into the DQL string handed to the query engine. Because the raw password is concatenated rather than parameterized or escaped, a quote character terminates the literal and trailing text is parsed as additional DQL blocks. The affected component is the Go module github.com/dgraph-io/dgraph (CPE pkg:go/github.com_dgraph-io_dgraph_v25), specifically deployments that include GraphQL support with the @secret directive enabling checkUserPassword. This is a distinct code path from CVE-2026-41328 and CVE-2026-41327, which fixed DQL injection in the mutation path (edgraph/server.go) and did not cover the query rewriter.
RemediationAI
Vendor-released patch: upgrade to Dgraph v25.3.4 (https://github.com/dgraph-io/dgraph/releases/tag/v25.3.4), which contains commit cee702c93f141eeb0c96a81f70830ec9e459efac escaping/parameterizing the checkpwd() password value; see advisory GHSA-q2m9-6jp9-c6mc for details. If you cannot upgrade immediately, restrict network exposure of the Alpha GraphQL endpoint (default :8080/graphql) so it is not internet-reachable - place it behind authentication, a reverse proxy, or a network ACL, accepting that this breaks legitimate external GraphQL clients. Where the @secret directive / checkUserPassword feature is not needed, remove it from the schema to eliminate the vulnerable path, at the cost of disabling password-check functionality. As an interim WAF/proxy control, reject GraphQL request bodies whose password argument contains double-quote or backslash characters, understanding this may block legitimate passwords containing those characters and can be bypassed via encoding, so it is a stopgap rather than a fix.
Same technique Denial Of Service
View allVendor StatusVendor
SUSE
Severity: Important| Product | Status |
|---|---|
| SUSE Linux Enterprise Server 16.1 | Affected |
| SUSE Linux Enterprise Server for SAP applications 16.1 | Affected |
| SUSE Linux Enterprise Module for Package Hub 15 SP5 | Affected |
| SUSE Linux Enterprise Module for Package Hub 15 SP6 | Affected |
| openSUSE Leap 15.5 | Affected |
| openSUSE Leap 15.6 | Affected |
Share
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-42237
GHSA-q2m9-6jp9-c6mc