Aug 20, 2026·6 min read·19 visits
Unauthenticated remote attackers can connect to Dgraph's public gRPC port and trigger an external snapshot stream, causing the underlying storage engine to immediately wipe and replace all database records without validation.
A critical vulnerability in Dgraph Alpha allows unauthenticated network clients to delete and replace database stores. The public gRPC interface on port 9080 processes external snapshot streams without enforcing authentication or authorization, triggering immediate database destruction via the storage engine's initialization process.
Dgraph is a highly performant, open-source distributed database designed for GraphQL and Graph workloads. It organizes architecture around two primary components: Zero nodes, which manage cluster state and metadata, and Alpha nodes, which store user data and indexes. The Alpha node exposes several interfaces, including a public-facing gRPC endpoint on port 9080, which serves client queries and system administrative operations.
The vulnerability identified as CVE-2026-54061 stems from a critical design flaw where sensitive streaming gRPC endpoints are exposed on this public port without authentication checks. Specifically, the RPC handlers designed to import external snapshots, such as StreamExtSnapshot, were completely unguarded. This exposed a massive, unauthenticated attack surface directly accessible by any network client capable of reaching the Alpha service.
This flaw is classified under CWE-306 (Missing Authentication for Critical Function). An unauthenticated remote attacker can connect to the target port, open a stream, and trigger the snapshot processing pipeline. The impact is severe, resulting in the immediate truncation and destruction of the target group's active database tables.
The underlying flaw is rooted in asymmetric middleware enforcement within Dgraph's gRPC server implementation. Prior to version 25.3.5, the server registered security interceptors solely for unary gRPC requests. These interceptors, which implement token validation (hasPoormansAuth) and Access Control List checks (AuthorizeGuardians), did not intercept bidirectional or unidirectional streaming connections.
When an external snapshot stream request arrived at StreamExtSnapshot, the system proceeded directly to the business logic handler without validating the client's identity or authorization. The handler immediately initiated a worker thread via runLocalSubscriber to process incoming key-value streams. This sub-process relied on the Badger key-value engine's native transactional APIs to apply the snapshot data.
As soon as the handler set up the subscriber thread, it initialized a StreamWriter instance from the Badger storage engine and executed its Prepare() method. In the design of the Badger storage engine, calling Prepare() executes an internal function named dropAll(). This routine drops all existing tables and writes to prepare the store for a clean state transition. Crucially, this operation happens before any stream metadata or payload packets are validated, meaning even an empty connection triggers total data loss.
To understand the technical mechanics, consider the vulnerable control flow inside worker/import.go. The original implementation executed the storage engine's initialization logic directly upon the establishment of the stream connection.
// VULNERABLE CODE (worker/import.go)
sw := pstore.NewStreamWriter()
defi sw.Cancel()
// This call was executed immediately when the stream was opened
if err := sw.Prepare(); err != nil {
return err
}Notice that there is no verification of whether the stream contains actual data packets before invoking sw.Prepare(). Additionally, the endpoint in edgraph/server.go lacked security checks:
// VULNERABLE CODE (edgraph/server.go)
func (s *Server) StreamExtSnapshot(stream api.Dgraph_StreamExtSnapshotServer) error {
defer x.ExtSnapshotStreamingState(false)
// Missing: AuthorizeGuardians(stream.Context())
// Missing: hasPoormansAuth(stream.Context())
return worker.ProcessExtSnapshot(stream)
}The official fix implemented in commit aba579acea0c6426dc64e78f64b857ad1c90db3e solves these issues systematically. It registers a stream interceptor AuditStreamGRPC to inspect streaming calls. Furthermore, it adds explicit authorization guardrails inside StreamExtSnapshot and delays sw.Prepare() execution until the first valid data packet is processed.
// PATCHED CODE (edgraph/server.go)
func (s *Server) StreamExtSnapshot(stream api.Dgraph_StreamExtSnapshotServer) error {
defer x.ExtSnapshotStreamingState(false)
// Enforce ACL guardian checks
if err := AuthorizeGuardians(stream.Context()); err != nil {
return err
}
// Enforce token security checks
if err := hasPoormansAuth(stream.Context()); err != nil {
return err
}
return worker.ProcessExtSnapshot(stream)
}Exploitation of CVE-2026-54061 does not require high-level attacker privileges or complex exploit payloads. The only prerequisite is unauthenticated network access to the target Dgraph Alpha node's public gRPC listener, which typically runs on TCP port 9080. The attacker does not need to bypass firewalls or authenticate with a valid JWT token.
An exploit sequence begins with the attacker constructing a raw gRPC client and initiating a connection to the dgraph.api.Dgraph service. The attacker invokes the streaming RPC StreamExtSnapshot and transmits an initial metadata packet containing the destination GroupId. Immediately afterward, the attacker transmits a termination frame containing a StreamPacket with the field Done set to true, then closes the socket connection.
Because the vulnerable server receives the stream and spawns the import worker immediately, it executes sw.Prepare() on contact. This instructs the Badger engine to execute dropAll(), wiping the entire database store for that target group. Since the attacker terminates the connection with a 'Done-only' packet and no actual data, the database remains completely empty and the active storage is destroyed.
The impact of this vulnerability is critical, directly compromising the Integrity and Availability of the Dgraph deployment. An attacker can execute a total database wipe with a single, unauthenticated gRPC request. This leads to immediate and permanent loss of production data unless offsite backups are maintained and actively monitored.
The Common Vulnerability Scoring System (CVSS) v3.1 base score for this vulnerability is 9.1, reflecting a critical severity rating. The vector is defined as CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H. Although confidentiality is marked as none because the exploit does not directly leak data to the attacker, the integrity and availability scores are both high.
While the vulnerability does not directly expose a read primitive, the threat model must consider secondary integrity impacts. An attacker who has wiped the database could subsequently populate it with malicious data payloads, fabricated transactional schemas, or modified credentials. This enables downstream administrative takeovers of downstream services that rely on the graph database.
The primary remediation strategy is to upgrade all Dgraph Alpha installations to version v25.3.5 or later. This release addresses the vulnerability by introducing the AuditStreamGRPC stream interceptor, enforcing authentication inside the streaming handlers, and delaying database modifications until valid snapshot data blocks are successfully validated.
If an immediate upgrade is not possible, operators must deploy network-level mitigations to shield vulnerable Alpha nodes. Dgraph Alpha ports, particularly port 9080, must never be exposed to the public internet or untrusted subnets. Configure network firewalls or cloud security groups to restrict ingress traffic on port 9080 to known, trusted services such as client microservices and Dgraph Zero coordinator nodes.
Additionally, administrators should verify that active security mechanisms are explicitly configured. Ensure that the --security token flag is set to enforce 'poor man's authentication' and that Access Control Lists (ACLs) are active. These configurations, coupled with strict firewall filtering, reduce the exposure of the vulnerable RPC endpoints to unauthorized actors.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
Dgraph Dgraph | < 25.3.5 | v25.3.5 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-306 |
| Attack Vector | Network |
| CVSS v3.1 | 9.1 (Critical) |
| Impact | Integrity & Availability (Data Loss) |
| Exploit Status | PoC Available |
| CISA KEV Status | Not Listed |
The application does not perform any authentication check for a critical function, allowing unauthorized actors to perform operations that should be restricted.
A heap-based buffer overflow vulnerability in Pillow PyPI binary wheels (versions 11.1.0 to 12.x) allows remote code execution or application crash via crafted JPEG 2000 files processed by the bundled libopenjp2 library.
CVE-2026-109618 (dubbed PHP2Shell) is a critical vulnerability in the PHP engine core resulting from improper out-of-memory exception handling via longjmp(). When request allocation fails mid-processing, non-local control flow bypasses cleanup procedures, leaving memory structures uninitialized or in a use-after-free state during request shutdown.
CVE-2026-109619 (PHP2Shell) is a critical Use-After-Free vulnerability in the core PHP engine caused by improper global state cleanup during out-of-memory exception handling across persistent worker requests.
In Python virtualenv prior to version 21.14.9, activation script generators and configuration writers use Path.exists() before writing files. Because Path.exists() resolves symbolic links, it returns False for dangling symlinks. Consequently, virtualenv skips unlinking pre-planted symbolic links or hard links, writing data directly to target locations outside the intended virtual environment directory.
A remote code execution vulnerability exists in Microsoft .NET due to untrusted data deserialization within the PresentationCore component. The flaw stems from implicit auto-conversion flags during clipboard data retrieval operations.
An out-of-bounds write vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio allows unauthenticated remote attackers to execute arbitrary code via crafted pixel-shader bytecode or auto-converted clipboard payloads.