VYPR
High severityCISA KEVNVD Advisory· Published Oct 5, 2021· Updated Oct 21, 2025

Snapshot authentication bypass in grafana

CVE-2021-39226

Description

Grafana is an open source data visualization platform. In affected versions unauthenticated and authenticated users are able to view the snapshot with the lowest database key by accessing the literal paths: /dashboard/snapshot/:key, or /api/snapshots/:key. If the snapshot "public_mode" configuration setting is set to true (vs default of false), unauthenticated users are able to delete the snapshot with the lowest database key by accessing the literal path: /api/snapshots-delete/:deleteKey. Regardless of the snapshot "public_mode" setting, authenticated users are able to delete the snapshot with the lowest database key by accessing the literal paths: /api/snapshots/:key, or /api/snapshots-delete/:deleteKey. The combination of deletion and viewing enables a complete walk through all snapshot data while resulting in complete snapshot data loss. This issue has been resolved in versions 8.1.6 and 7.5.11. If for some reason you cannot upgrade you can use a reverse proxy or similar to block access to the literal paths: /api/snapshots/:key, /api/snapshots-delete/:deleteKey, /dashboard/snapshot/:key, and /api/snapshots/:key. They have no normal function and can be disabled without side effects.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/grafana/grafanaGo
< 7.5.117.5.11
github.com/grafana/grafanaGo
>= 8.0.0, < 8.1.68.1.6

Affected products

1

Patches

1
2d456a637585

Fix static path matching issue in macaron

https://github.com/grafana/grafanaKevin MinehartSep 17, 2021via ghsa
2 files changed · +15 4
  • pkg/api/dashboard_snapshot.go+9 0 modified
    @@ -146,6 +146,9 @@ func CreateDashboardSnapshot(c *models.ReqContext, cmd models.CreateDashboardSna
     // 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)
    @@ -215,6 +218,9 @@ func deleteExternalDashboardSnapshot(externalUrl string) error {
     // GET /api/snapshots-delete/:deleteKey
     func DeleteDashboardSnapshotByDeleteKey(c *models.ReqContext) response.Response {
     	key := c.Params(":deleteKey")
    +	if len(key) == 0 {
    +		return response.Error(404, "Snapshot not found", nil)
    +	}
     
     	query := &models.GetDashboardSnapshotQuery{DeleteKey: key}
     
    @@ -245,6 +251,9 @@ func DeleteDashboardSnapshotByDeleteKey(c *models.ReqContext) response.Response
     // DELETE /api/snapshots/:key
     func DeleteDashboardSnapshot(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}
     
    
  • pkg/macaron/router.go+6 4 modified
    @@ -289,10 +289,12 @@ func (r *Router) SetHandlerWrapper(f func(Handler) Handler) {
     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())
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

18

News mentions

0

No linked articles in our index yet.