Aug 20, 2026·6 min read·3 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 security vulnerability in Copier versions 9.5.0 through 9.15.1 allows unauthenticated remote code execution via crafted HTTP requests or local paths containing traversal sequences. The trust-evaluation mechanism compares target repository paths or URLs against trusted prefixes using unnormalized string comparison, while the subsequent fetching mechanism normalizes the path before cloning. Attackers can exploit this asymmetry to bypass security warning prompts and execute arbitrary commands under the local user context.
GeoLens before version 1.2.4 contains multiple critical-tier security vulnerabilities including improper authorization in metadata access, tile cache scope leakage, dataset title enumeration, weak default credentials, and denial of service via STAC POST search.
CVE-2026-55694 is a chained Information Disclosure and Insecure Direct Object Reference (IDOR) vulnerability in Snipe-IT prior to version 8.6.3. The vulnerability allows authenticated, restricted users to completely bypass randomized file-naming security controls, leak the obfuscated filenames of signed End User License Agreements (EULAs), and subsequently download these confidential documents across tenant boundaries.
Snipe-IT is an IT asset/license management system. Prior to 8.6.3, any activated account can request /maintenances/{id} and read maintenance records for assets in the same company without asset or maintenance permission. app/Http/Controllers/MaintenancesController.php show() renders the record without authorize(), while company-scoped route-model binding only prevents access to other companies. Disclosed fields include asset tags, suppliers, purchase costs, notes, and dates. This issue is fixed in version 8.6.3.
A Stored DOM-based Cross-Site Scripting (DOM XSS) vulnerability exists in Snipe-IT versions prior to 8.6.2. The vulnerability occurs when a stored manufacturer or supplier name is converted to CamelCase and rendered within the 'data-selected-count-id' attribute of a table. Client-side JavaScript retrieves this decoded attribute and performs unsafe string concatenation, passing it directly into jQuery's '.after()' method, enabling authenticated attackers to execute arbitrary JavaScript in the victim's session.
CVE-2026-62673 (also known as CVE-2026-62230 and GHSA-vwg3-w8w3-pc79) is a high-severity security bypass vulnerability in the Grav CMS. It permits unauthenticated remote attackers to circumvent directory and file access policies defined in Apache .htaccess. This flaw allows direct retrieval of sensitive configuration files, system-level credentials, and database equivalents from case-insensitive host filesystems.