Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2021-39226

CVE-2021-39226: Grafana Auth Bypass Vulnerability

CVE-2021-39226 is an authentication bypass vulnerability in Grafana that allows unauthorized access to and deletion of snapshots. This post covers technical details, affected versions, impact, and mitigation strategies.

Published:

CVE-2021-39226 Overview

CVE-2021-39226 is an authentication bypass vulnerability in Grafana, an open source data visualization platform. In affected versions, both unauthenticated and authenticated users can view dashboard snapshots with the lowest database key by accessing specific literal paths: /dashboard/snapshot/:key or /api/snapshots/:key. When the public_mode configuration setting is enabled, unauthenticated users can also delete snapshots. This vulnerability enables attackers to enumerate and exfiltrate all snapshot data while simultaneously causing complete data loss through sequential deletion.

Critical Impact

This vulnerability is listed in CISA's Known Exploited Vulnerabilities (KEV) catalog, indicating active exploitation in the wild. Attackers can systematically walk through all snapshot data, exposing sensitive dashboard information and causing irreversible data loss.

Affected Products

  • Grafana versions prior to 7.5.11
  • Grafana versions 8.x prior to 8.1.6
  • Fedora 34 and 35 (grafana package)

Discovery Timeline

  • 2021-10-05 - CVE-2021-39226 published to NVD
  • 2025-10-24 - Last updated in NVD database

Technical Details for CVE-2021-39226

Vulnerability Analysis

This vulnerability stems from improper access control (CWE-862) and authentication bypass (CWE-287) in Grafana's snapshot handling functionality. The core issue lies in how Grafana's macaron router handles static path matching for snapshot-related endpoints.

The vulnerability allows complete enumeration of snapshot data because the affected endpoints accept literal :key strings instead of properly validating route parameters. When a request is made to /api/snapshots/:key with the literal string :key, the router's fast-match logic for static routes incorrectly matches this path, returning the snapshot with the lowest database key rather than requiring a valid snapshot key.

This creates two attack scenarios: First, iterative viewing allows attackers to access each snapshot sequentially by viewing and deleting snapshots one by one. Second, when public_mode is enabled, even unauthenticated attackers can perform this enumeration, significantly expanding the attack surface.

Root Cause

The root cause is a static path matching issue in Grafana's embedded macaron router. The router's ServeHTTP function performs a fast-match optimization for static routes before checking for dynamic path parameters. When the URL path contains literal colon (:) or asterisk (*) characters, the router should skip static matching and proceed to dynamic route matching. However, the vulnerable code path allowed requests with literal :key in the URL to match static routes, bypassing the intended parameter validation.

Additionally, the GetDashboardSnapshot handler did not validate that the key parameter was actually populated, allowing requests with empty or malformed keys to proceed.

Attack Vector

The attack is network-based and requires no authentication in default configurations for viewing snapshots, or when public_mode is enabled for deletion. An attacker can:

  1. Access /api/snapshots/:key to retrieve the snapshot with the lowest database key
  2. Delete that snapshot via /api/snapshots-delete/:deleteKey (if authenticated or if public_mode=true)
  3. Repeat to enumerate through all snapshots in the database
go
// Security patch in pkg/api/dashboard_snapshot.go - Fix static path matching issue in macaron
// Source: https://github.com/grafana/grafana/commit/2d456a6375855364d098ede379438bf7f0667269

 // GET /api/snapshots/:key
 func GetDashboardSnapshot(c *models.ReqContext) response.Response {
 	key := c.Params(":key")
+	if len(key) == 0 {
+		return response.Error(404, "Snapshot not found", nil)
+	}
 	query := &models.GetDashboardSnapshotQuery{Key: key}
 
 	err := bus.Dispatch(query)
go
// Security patch in pkg/macaron/router.go - Fix static path matching issue in macaron
// Source: https://github.com/grafana/grafana/commit/2d456a6375855364d098ede379438bf7f0667269

 func (r *Router) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 	if t, ok := r.routers[req.Method]; ok {
 		// Fast match for static routes
-		leaf := r.getLeaf(req.Method, req.URL.Path)
-		if leaf != nil {
-			leaf.handle(rw, req, nil)
-			return
+		if !strings.ContainsAny(req.URL.Path, ":*") {
+			leaf := r.getLeaf(req.Method, req.URL.Path)
+			if leaf != nil {
+				leaf.handle(rw, req, nil)
+				return
+			}
 		}
 
 		h, p, ok := t.Match(req.URL.EscapedPath())

Detection Methods for CVE-2021-39226

Indicators of Compromise

  • HTTP requests to /api/snapshots/:key or /dashboard/snapshot/:key containing literal colon characters
  • Sequential requests to snapshot deletion endpoints /api/snapshots-delete/:deleteKey
  • Unusual patterns of snapshot access followed by deletion from the same source
  • Web server logs showing 200 responses to malformed snapshot key requests

Detection Strategies

  • Monitor web access logs for requests containing literal :key or :deleteKey strings in snapshot-related URLs
  • Implement alerting on rapid sequential access to snapshot endpoints from single IP addresses
  • Review Grafana audit logs for unexpected snapshot deletions or access patterns
  • Deploy web application firewall (WAF) rules to block requests with literal route parameter syntax

Monitoring Recommendations

  • Enable detailed access logging on Grafana instances and forward to SIEM
  • Create alerts for any requests matching /api/snapshots/:key or /api/snapshots-delete/:deleteKey patterns
  • Monitor for sudden decreases in snapshot counts which may indicate exploitation
  • Track authentication failures and unusual access patterns to dashboard snapshot endpoints

How to Mitigate CVE-2021-39226

Immediate Actions Required

  • Upgrade Grafana to version 8.1.6 or later for 8.x installations
  • Upgrade Grafana to version 7.5.11 or later for 7.x installations
  • If immediate upgrade is not possible, implement reverse proxy rules to block affected paths
  • Review snapshot access logs for signs of prior exploitation
  • Audit existing snapshots and restore from backup if data loss is suspected

Patch Information

Grafana has released security patches in versions 8.1.6 and 7.5.11. The fix addresses both the router-level static path matching issue and adds validation in the snapshot handler to reject empty key parameters. For detailed information, see the Grafana Release Notes for 7.5.11 and Grafana Release Notes for 8.1.6. The security advisory is available at GitHub Grafana Security Advisory GHSA-69j6-29vr-p3j9.

Workarounds

  • Use a reverse proxy (nginx, Apache, HAProxy) to block access to vulnerable paths
  • The affected literal paths have no normal function and can be safely blocked without side effects
  • Disable public_mode configuration to require authentication for snapshot deletion
  • Consider temporarily disabling snapshot functionality entirely if patches cannot be applied
bash
# Nginx configuration to block vulnerable paths
location ~ ^/api/snapshots/:key$ {
    deny all;
    return 404;
}

location ~ ^/api/snapshots-delete/:deleteKey$ {
    deny all;
    return 404;
}

location ~ ^/dashboard/snapshot/:key$ {
    deny all;
    return 404;
}

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.