← Back to Feed CACHED · 2026-09-22 01:27:34 · CACHE_KEY tenable:297197
tenable:297197 · CWE-639 · Disclosed 2026-01-27

Grafana Labs 10.2.0 < 11.6.9+security-01 / 12.0.0 < 12.0.8+sec...

ASSESSED — NOISGATE
Vendor
Reassessed
Verdict:
Do you agree?
01 · The Real Story

Like a hotel manager whose master key works on every floor — but they already had to be staff to get a key at all

CVE-2026-21721 is a broken access-control bug in Grafana's dashboard permissions API. The endpoint that manages per-dashboard ACLs checks only that the caller holds the dashboards.permissions:* action — it never validates that the caller is actually authorized *for the specific dashboard being modified*. An authenticated user who legitimately manages permissions on Dashboard A can therefore read and rewrite permissions on Dashboards B through Z. Affected versions span 10.2.0 through 11.6.8, 12.0.0–12.0.7, 12.1.0–12.1.4, 12.2.0–12.2.2, and 12.3.0. Patched releases are 11.6.9+security-01, 12.0.8+security-01, 12.1.5+security-01, 12.2.3+security-01, and 12.3.1+security-01.

Grafana and Red Hat both stamp this HIGH / 8.1, but the CVSS score overweights the theoretical ceiling and ignores the prerequisite chain. The vector AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N counts PR as Low, yet the *actual* prerequisite is not merely 'any authenticated user' — it's a user who already holds the dashboards.permissions:* action on at least one dashboard. In most orgs that population is dashboard admins and Grafana Org Admins, i.e., a small, already-privileged cohort. The impact is confined to dashboard ACL manipulation within one Grafana organization — not RCE, not data-source credential theft, not system compromise. With no public PoC, no KEV listing, no in-the-wild activity, and an EPSS of 0.67% (49th percentile), the vendor severity is materially inflated.

"Dashboard admin scope leak is auth-gated, no-PoC, no-KEV — MEDIUM not HIGH."
02 · The Attack Path

5 steps from start to impact.

STEP 01

Obtain authenticated Grafana session

The attacker must possess valid credentials for the target Grafana instance. This can be a local account, an LDAP/OAuth-federated identity, or a service account token. Without authentication the permissions API returns 401 and the chain is dead.
Conditions required:
  • Valid Grafana user credentials or API key
  • Network reachability to the Grafana HTTP(S) port (default 3000)
Where this breaks in practice:
  • Enterprise Grafana is usually behind SSO/MFA via OAuth or SAML — credential theft is non-trivial
  • Many deployments are internal-only, not internet-facing
Detection/coverage: Failed-login alerting, anomalous session-origin detection in SIEM
STEP 02

Hold dashboards.permissions:* action on at least one dashboard

The Grafana RBAC model gates permission-management behind the dashboards.permissions:read and dashboards.permissions:write actions. These are NOT granted to Viewers or basic Editors by default — they're assigned to Dashboard Admins, Folder Admins, or Org Admins. The attacker must already occupy one of these roles to enter the vulnerable code path.
Conditions required:
  • User role includes dashboards.permissions:* on ≥1 dashboard
  • Grafana RBAC is configured (default on 10.x+)
Where this breaks in practice:
  • Default Viewer and Editor roles lack this action entirely
  • In large orgs, only a handful of power users or automation service accounts hold dashboard-admin permissions
  • Org Admin accounts are typically tightly controlled
Detection/coverage: Grafana audit logs (Enterprise) record permission changes; unusual PATCH /api/dashboards/:uid/permissions calls are detectable
STEP 03

Enumerate target dashboard UIDs

The attacker needs to discover the UIDs of dashboards whose permissions they want to manipulate. This can be done via the /api/search endpoint, which returns dashboards the caller can see. Even without direct view access, dashboard titles and UIDs may be enumerable depending on folder permissions.
Conditions required:
  • Authenticated session from Step 1
  • Some level of search/browse access
Where this breaks in practice:
  • Folder-level ACLs may limit dashboard discovery
  • Grafana audit logs capture search API usage
Detection/coverage: Spike in /api/search calls or sequential dashboard enumeration in access logs
STEP 04

Modify permissions on out-of-scope dashboards

The attacker sends POST /api/dashboards/:uid/permissions targeting a dashboard UID they do NOT legitimately manage. Because the API only checks for the dashboards.permissions:* action globally and not against the specific dashboard, the request succeeds. The attacker can grant themselves Viewer or Editor access on the target dashboard, or grant access to a collaborator account.
Conditions required:
  • Steps 1–3 completed
  • Target dashboard UID known
Where this breaks in practice:
  • Permission change is logged in Grafana's audit trail (Enterprise edition)
  • Grafana alerting on permission-change events can trigger near-real-time notification
  • The attacker is modifying ACLs, not directly exfiltrating data — a second step is needed to view dashboard content
Detection/coverage: Grafana Enterprise audit log events for permission changes; SIEM correlation on dashboards.permissions API calls across different dashboard scopes
STEP 05

Access sensitive dashboard content

With newly granted permissions, the attacker navigates to or API-queries the target dashboard. They can now view metrics, annotations, and panel data that were previously access-controlled. In the worst case this exposes business KPIs, infrastructure metrics, or security monitoring panels — but NOT underlying data-source credentials or query secrets, which are managed separately.
Conditions required:
  • Permission modification from Step 4 succeeded
  • Dashboard contains data of value to the attacker
Where this breaks in practice:
  • Dashboard data is observability metrics, not typically PII or regulated data
  • Data-source credentials remain hidden behind Grafana's secret store — this vuln does NOT expose them
  • Impact requires the target dashboards to contain meaningfully sensitive information
Detection/coverage: Access logs showing the attacker's user viewing dashboards they historically never accessed
03 · Intelligence Metadata

The supporting signals.

In-the-Wild ExploitationNo evidence. Not listed in CISA KEV. No vendor, CERT, or threat-intel reports of active exploitation as of September 2026.
Proof-of-ConceptNone public. No PoC repositories (nomi-sec/PoC-in-GitHub, SecureWithUmer/CVE-2026-PoCs) index a working exploit. The API call is trivial to construct but requires authenticated, privileged access.
EPSS0.67% (49th percentile) — below the median exploitation probability, consistent with the auth-gated, narrow-prerequisite profile.
CISA KEVNot listed as of 2026-09-22.
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N — Network-attackable, low complexity, low privilege, no user interaction. C:H and I:H reflect dashboard-ACL read/write. A:N because no denial-of-service path exists.
Affected Versions10.2.0–11.6.8, 12.0.0–12.0.7, 12.1.0–12.1.4, 12.2.0–12.2.2, 12.3.0
Fixed Versions11.6.9+security-01, 12.0.8+security-01, 12.1.5+security-01, 12.2.3+security-01, 12.3.1+security-01. Red Hat backports: RHSA-2026:2914, RHSA-2026:2920, RHSA-2026:3078, RHSA-2026:3529, RHSA-2026:5633, RHSA-2026:8229.
Internet Exposure~600,000+ Grafana instances internet-reachable per ZoomEye scans. Shodan indexes ~5,000+ via default port 3000. However, exploitation requires *authenticated, permission-privileged* access — raw exposure count is misleading for this CVE.
DisclosurePublished 2026-01-27 by Grafana Labs. Discovered by researcher se1en via Grafana's bug bounty program.
Vendor AdvisoriesGrafana SA, Red Hat CVE, Tenable Plugin 297197
04 · The Call

Final Verdict
DOWNGRADED to MEDIUM (5.5/10)

Why this verdict

  • Authentication gate: The entire chain requires a valid, authenticated Grafana session. In enterprise deployments with SSO/MFA, obtaining this is non-trivial and implies the attacker is already an insider or has compromised credentials through a separate vector.
  • Narrow privilege prerequisite: The vulnerable code path is only reachable by users holding dashboards.permissions:* — a privilege typically restricted to Dashboard Admins, Folder Admins, or Org Admins. This is NOT a default Viewer or Editor capability. The realistic attacker population is a small fraction of the user base.
  • Impact ceiling is dashboard ACLs, not system compromise: The worst outcome is reading and modifying *dashboard permissions* within one Grafana organization. There is no path to RCE, no data-source credential exposure, no lateral movement, and no availability impact. The CVSS C:H/I:H ratings describe the dashboard-permission scope, not system-level impact.
  • No exploitation pressure: Zero public PoCs, zero KEV listing, zero in-the-wild reports after 8 months of disclosure. EPSS at 0.67% (49th percentile) confirms low predicted exploitation probability.
  • Role multiplier: Grafana is an observability platform, not canonically a high-value-role component (not an IdP, hypervisor, PAM, CA, CI/CD, backup engine, kernel-mode agent, or network edge appliance). In its typical deployment role — monitoring dashboards for engineering and ops teams — the blast radius of dashboard ACL manipulation is *organization-internal, data-plane-only*. Even in a high-value deployment (e.g., Grafana monitoring a SOC's security metrics), the chain succeeds only for already-privileged dashboard admins and the outcome is dashboard-level visibility, not domain takeover, fleet compromise, or supply-chain pivot. This does not meet the HIGH floor criteria.

Why not higher?

Upgrading to HIGH would require either active exploitation, a public weaponized PoC, or a blast radius that reaches fleet/domain/identity-scale compromise. None of these conditions are met. The vulnerability is entirely confined to dashboard ACL manipulation within one Grafana org, requires an already-privileged authenticated user, and has generated zero exploitation interest in 8 months. The 600k+ internet-exposed Grafana instances are irrelevant because this is not an unauth bug.

Why not lower?

Downgrading to LOW would underweight the real risk that a malicious insider with dashboard-admin rights can silently escalate visibility across an entire Grafana organization's dashboards. In environments where Grafana monitors sensitive infrastructure (production databases, cloud spend, security alerts), unauthorized dashboard access has meaningful confidentiality impact. The attack is also trivial to execute for someone who already holds the prerequisite permissions — no exploit development required, just an API call.

05 · Compensating Control

What to do — in priority order.

  1. Audit and minimize dashboards.permissions:* grants — Review Grafana RBAC assignments and remove dashboards.permissions:write from any user or service account that does not strictly need it. This directly eliminates the attacker population for this CVE. Complete within the 365-day noisgate remediation SLA window, but start immediately as it's good hygiene regardless.
  2. Enable Grafana Enterprise audit logging — If running Grafana Enterprise, enable the audit log and forward dashboards.permissions change events to your SIEM. This provides detection coverage for exploitation attempts until the patch is applied.
  3. Restrict Grafana network exposure — Ensure Grafana is not directly internet-facing. Place it behind a reverse proxy with SSO/MFA enforcement. While this CVE requires authentication, reducing the attack surface limits credential-stuffing and token-theft vectors that could feed into this chain.
  4. Apply the vendor patch within 365 days — Update to 11.6.9+security-01, 12.0.8+security-01, 12.1.5+security-01, 12.2.3+security-01, or 12.3.1+security-01 depending on your release train. As a MEDIUM-severity finding with no mitigation SLA, go straight to the remediation window. RHEL users can apply the relevant RHSA errata (2026:2914, 2026:3078, etc.).
What doesn't work
  • WAF rules — The exploit uses legitimate Grafana API endpoints with valid authentication tokens. No WAF signature can distinguish a legitimate permission change from an out-of-scope one; the authorization logic is server-side.
  • Network segmentation alone — Segmenting Grafana from the internet helps, but the attacker population is *authenticated insiders with dashboard-admin rights*. Network controls don't address insider threat.
  • Rotating Grafana admin passwords — The vulnerability doesn't require Org Admin or Grafana Server Admin credentials. It's exploitable by any user with dashboards.permissions:* on a single dashboard, which is a much lower bar than admin access.
06 · Verification

Crowdsourced verification payload.

Run this on your Grafana server or any host with curl and network access to the Grafana API. Invoke as: bash check_cve_2026_21721.sh https://grafana.example.com. No authentication required — it queries the unauthenticated /api/health endpoint for version info.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_cve_2026_21721.sh — Detect CVE-2026-21721 (Grafana dashboard permissions scope bypass)
# Usage: bash check_cve_2026_21721.sh <GRAFANA_BASE_URL>
# Exit codes: 0=VULNERABLE, 1=PATCHED, 2=UNKNOWN

set -euo pipefail

GRAFANA_URL="${1:-}"
if [[ -z "$GRAFANA_URL" ]]; then
  echo "Usage: $0 <GRAFANA_BASE_URL>"
  echo "Example: $0 https://grafana.example.com"
  exit 2
fi

# Strip trailing slash
GRAFANA_URL="${GRAFANA_URL%/}"

# Fetch version from health endpoint
VERSION=$(curl -sk --max-time 10 "${GRAFANA_URL}/api/health" 2>/dev/null | grep -oP '"version"\s*:\s*"\K[^"]+' || true)

if [[ -z "$VERSION" ]]; then
  echo "UNKNOWN — Could not retrieve Grafana version from ${GRAFANA_URL}/api/health"
  exit 2
fi

echo "Detected Grafana version: $VERSION"

# Strip +security-01 or similar suffixes for comparison, but note their presence
HAS_SECURITY_SUFFIX=0
if [[ "$VERSION" == *"+security"* ]]; then
  HAS_SECURITY_SUFFIX=1
fi

# Extract base version (strip everything after +)
BASE_VERSION=$(echo "$VERSION" | sed 's/+.*//')

# Version comparison function
ver() { printf '%03d%03d%03d' $(echo "$1" | tr '.' ' '); }

V=$(ver "$BASE_VERSION")

# Check affected ranges:
# 10.2.0 - 11.6.8 → fixed in 11.6.9+security-01
# 12.0.0 - 12.0.7 → fixed in 12.0.8+security-01
# 12.1.0 - 12.1.4 → fixed in 12.1.5+security-01
# 12.2.0 - 12.2.2 → fixed in 12.2.3+security-01
# 12.3.0          → fixed in 12.3.1+security-01

VULNERABLE=0

if [[ $V -ge $(ver "10.2.0") && $V -le $(ver "11.6.8") ]]; then
  VULNERABLE=1
elif [[ $V -eq $(ver "11.6.9") && $HAS_SECURITY_SUFFIX -eq 0 ]]; then
  # 11.6.9 without +security-01 may still be vulnerable
  VULNERABLE=1
elif [[ $V -ge $(ver "12.0.0") && $V -le $(ver "12.0.7") ]]; then
  VULNERABLE=1
elif [[ $V -eq $(ver "12.0.8") && $HAS_SECURITY_SUFFIX -eq 0 ]]; then
  VULNERABLE=1
elif [[ $V -ge $(ver "12.1.0") && $V -le $(ver "12.1.4") ]]; then
  VULNERABLE=1
elif [[ $V -eq $(ver "12.1.5") && $HAS_SECURITY_SUFFIX -eq 0 ]]; then
  VULNERABLE=1
elif [[ $V -ge $(ver "12.2.0") && $V -le $(ver "12.2.2") ]]; then
  VULNERABLE=1
elif [[ $V -eq $(ver "12.2.3") && $HAS_SECURITY_SUFFIX -eq 0 ]]; then
  VULNERABLE=1
elif [[ $V -eq $(ver "12.3.0") ]]; then
  VULNERABLE=1
fi

if [[ $VULNERABLE -eq 1 ]]; then
  echo "VULNERABLE — Grafana $VERSION is affected by CVE-2026-21721"
  echo "Upgrade to the corresponding +security-01 release for your branch."
  exit 0
else
  echo "PATCHED — Grafana $VERSION is not affected by CVE-2026-21721"
  exit 1
fi
07 · Sources

Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.