← Back to Feed CACHED · 2026-09-22 02:07:55 · CACHE_KEY tenable:208027
tenable:208027 · CWE-653 · Disclosed 2024-09-26

Grafana Labs Incorrect Permission

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

Like finding out a hotel guest with pool access can also use the hot tub — it's a policy error, not a break-in

CVE-2024-8118 is an RBAC permission check error in Grafana's alerting subsystem affecting versions 8.5.0 through 11.2.0 (fixed in 11.2.1, 11.1.6, 11.0.5, 10.4.9, 10.3.10). The /api/ruler/{DatasourceUID}/api/v1/rules/{Namespace} endpoint — which manages alerting and recording rules stored in external datasources — was documented to enforce alert.rules.external:write but actually checked for alert.instances.external:write. An authenticated user who already held instance-write permission on external datasources could therefore create, edit, and delete alert *rules* on those same datasources without explicit authorization. Impact is limited to alert rule manipulation and potential data leakage from datasource queries routed through crafted notification channels.

Grafana's vendor rating of MEDIUM (5.1 CVSS v4) slightly overstates the real-world risk. The CVSS vector already encodes PR:H (high privileges required) and VC/VI/VA all at Low, which is accurate — but it doesn't capture how narrow the permission gap actually is. The attacker must already hold alert.instances.external:write, a non-trivial RBAC grant that few users receive. The delta between 'can write alert instances' and 'can write alert rules' on external datasources is a marginal privilege escalation within a single application subsystem, not a path to infrastructure compromise. With no public PoC, no exploitation in the wild, no KEV listing, and an EPSS at the 46th percentile, this reads as a compliance fix rather than an urgent threat.

"Narrow RBAC gap in Grafana alerting requires privileged insider, delivers limited impact"
02 · The Attack Path

3 steps from start to impact.

STEP 01

Obtain authenticated Grafana session with instance-write permission

The attacker must hold valid credentials for a Grafana account that has been explicitly granted the alert.instances.external:write RBAC permission. This is not a default role — it requires an administrator to have assigned this permission to the user or a custom role. The attacker authenticates normally via the Grafana UI or API.
Conditions required:
  • Valid Grafana credentials
  • Account with alert.instances.external:write RBAC grant
  • Network access to the Grafana instance
Where this breaks in practice:
  • Most Grafana deployments use Viewer/Editor/Admin built-in roles — custom RBAC with granular external alerting permissions is an Enterprise or Grafana Cloud feature
  • The target user population (people with instance-write but not rule-write on external datasources) is inherently small
  • Internal Grafana instances are typically not internet-facing
Detection/coverage: Authentication logs in Grafana audit log; SIEM correlation on Grafana login events
STEP 02

Call the alert rule write API endpoint

The attacker sends a PUT or POST request to /api/ruler/{DatasourceUID}/api/v1/rules/{Namespace} to create, modify, or delete alert rules on the external datasource. Because the endpoint checks alert.instances.external:write instead of alert.rules.external:write, the request is authorized despite the user lacking the correct permission. No exploit tooling is needed — this is a standard API call using curl, Postman, or the Grafana SDK.
Conditions required:
  • External datasource must be configured and have alerting enabled
  • Attacker knows the DatasourceUID and Namespace
Where this breaks in practice:
  • External datasource alerting (e.g., Cortex/Mimir ruler) must be explicitly configured — many Grafana deployments use only built-in Grafana alerting, which is NOT affected
  • The attacker needs to know valid DatasourceUID and Namespace values, which requires prior reconnaissance within the Grafana UI or API
Detection/coverage: Grafana audit logs capture API calls to the ruler endpoint; anomalous rule creation by non-admin accounts is detectable
STEP 03

Manipulate alert rules or exfiltrate data via notifications

With rule-write access, the attacker can create alerting rules that execute arbitrary PromQL/LogQL/datasource-native queries against the external datasource, potentially extracting data the attacker's role should not access. Exfiltration occurs by routing query results through notification channels (email, Slack, webhook) attached to the crafted rule. Alternatively, the attacker can suppress or modify existing alert rules to blind defenders.
Conditions required:
  • Notification channels must be configured and accessible
  • Datasource must contain data of interest beyond what the attacker already has access to
Where this breaks in practice:
  • Notification channel configuration is typically admin-controlled — the attacker may not be able to create new channels
  • Alert rule changes are visible in the Grafana UI to other users and admins
  • Data leakage via notifications is low-bandwidth and noisy
Detection/coverage: Notification channel activity monitoring; Grafana alert rule change audit trail; outbound webhook monitoring by network security tools
03 · Intelligence Metadata

The supporting signals.

In-the-Wild ExploitationNone observed. No reports of active exploitation from any threat intelligence source. Not listed in CISA KEV catalog.
Proof-of-ConceptNone public. No PoC repositories, blog posts, or researcher demonstrations found. Exploitation requires only a standard API call — no specialized tooling needed, but no weaponized exploit exists.
EPSS Score0.00583 (0.58%) — 46th percentile. Well below the threshold that would indicate meaningful exploit probability within 30 days.
KEV StatusNot listed. CVE-2024-8118 has not been added to the CISA Known Exploited Vulnerabilities catalog as of September 2026.
CVSS VectorCVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:L/VI:L/VA:L/SC:N/SI:N/SA:N — 5.1 Medium. Key takeaway: PR:H means high privileges required; all impact dimensions are Low. No v3.1 vector was published by the vendor or NVD.
Affected VersionsGrafana 8.5.0 through 11.2.0 — spanning roughly 3 years of releases across 5 major version lines.
Fixed Versions11.2.1, 11.1.6, 11.0.5, 10.4.9, 10.3.10. No distro backport advisories found for RHEL/Debian/Ubuntu — Red Hat marked this as *Will not fix* for their Grafana packages.
Internet ExposureShodan indexes ~46,000+ internet-facing Grafana instances globally. However, this CVE requires authenticated privileged access, so internet exposure alone does not constitute exploitability.
Disclosure Date2024-09-26 — disclosed and patched simultaneously by Grafana Labs.
ReporterNot publicly attributed. Discovered and fixed internally by Grafana Labs.
04 · The Call

Final Verdict
DOWNGRADED to LOW (4.0/10)

Why this verdict

  • Privilege floor is high: The attacker must already hold alert.instances.external:write — a non-default, granular RBAC permission that enterprises assign to a small subset of Grafana users. This is not a viewer-to-admin escalation; it's a lateral step within the alerting permission model.
  • Permission delta is narrow: The gap between 'can write alert instances on external datasources' and 'can write alert rules on external datasources' represents a marginal trust boundary violation within a single application subsystem. The two permissions are adjacent in Grafana's RBAC hierarchy.
  • External datasource alerting is a niche feature: This bug only affects the external ruler API (Cortex/Mimir/Loki ruler). Deployments using Grafana's built-in alerting engine — which is the default — are not affected. This significantly narrows the vulnerable population.
  • Impact ceiling is Low/Low/Low: Even upon successful exploitation, the attacker can only manipulate alert rules and potentially leak bounded query results via notifications. No RCE, no lateral movement, no credential access, no persistence outside Grafana.
  • Role multiplier: Grafana is deployed as an observability/dashboarding tool. (a) *Low-value role (dev/sandbox):* the chain succeeds but impact is negligible — test data only. (b) *Typical role (monitoring server):* the chain succeeds but blast radius is confined to alert rule tampering on one Grafana instance — host-level impact at most. (c) *High-value role (SIEM/detection plane):* In environments where Grafana serves as the alerting frontend for production monitoring or security telemetry, an insider could suppress detection rules. However, Grafana is a visualization layer, not a SIEM engine — alert rules live in the external ruler (Cortex/Mimir), and the attacker's changes are auditable and visible in the UI. Blast radius is tenant-level at most, not domain/fleet/supply-chain. This does not meet the HIGH floor threshold because ≤5% of Grafana installs use external ruler alerting as their sole detection mechanism, and the impact does not reach domain takeover or fleet compromise.
  • Zero exploitation signal: No PoC, no ITW exploitation, no KEV listing, EPSS at 46th percentile — all indicators point to a non-weaponized finding.

Why not higher?

Upgrading to MEDIUM would require either a broader impact surface or evidence of real-world exploitation interest. Neither exists. The permission gap is narrow enough that the practical security delta is marginal — the attacker already holds a trust-adjacent permission. External ruler alerting adoption is a fraction of the Grafana install base, further limiting the vulnerable population. Even in the worst-case SIEM-adjacent deployment, the outcome is alert rule tampering visible in audit logs, not silent infrastructure compromise.

Why not lower?

Dropping to IGNORE would be inappropriate because this *is* a genuine authorization bypass — a user gains write access to a resource they should not be able to modify. In a multi-tenant Grafana environment or a SOC using Grafana for alert management, an insider manipulating detection rules represents a real (if bounded) integrity concern. The fix is also trivial to apply, making remediation worthwhile during normal patch cycles.

05 · Compensating Control

What to do — in priority order.

  1. Audit and restrict alert.instances.external:write grants — Review Grafana RBAC role assignments and ensure alert.instances.external:write is granted only to users who also legitimately need alert.rules.external:write. In most orgs, these should be the same people, which effectively neutralizes the bug. Complete this audit as part of normal backlog hygiene — no noisgate mitigation SLA applies for LOW severity.
  2. Enable and monitor Grafana audit logging — Ensure Grafana's audit log is enabled and forwarded to your SIEM. Monitor for unexpected API calls to /api/ruler/*/api/v1/rules/* by non-admin accounts. This provides detection-in-depth regardless of patch status.
  3. Restrict network access to the Grafana API — If Grafana is internet-facing, place the /api/ruler/ path behind authentication enforcement and IP allowlisting at your reverse proxy or WAF layer. This is good hygiene independent of this CVE.
  4. Upgrade to a fixed Grafana version during next maintenance window — Apply the vendor patch (11.2.1+, 11.1.6+, 11.0.5+, 10.4.9+, 10.3.10+) within the noisgate remediation SLA of 365 days for LOW severity. No accelerated timeline is warranted given the absence of exploitation activity.
What doesn't work
  • Network segmentation alone — this is an authenticated, application-layer RBAC bypass. If the attacker is an authorized Grafana user on the internal network, network controls do not prevent exploitation.
  • WAF rules — the API call is a legitimate-looking PUT/POST to a standard Grafana endpoint with valid authentication. No WAF signature can distinguish a legitimate rule write from an unauthorized one at the HTTP layer.
  • Disabling Grafana alerting entirely — this would mitigate the CVE but destroys legitimate monitoring functionality, which is disproportionate for a LOW-severity finding.
06 · Verification

Crowdsourced verification payload.

Run this script on the Grafana server host (or any machine with network access to the Grafana API) as any user. It queries the Grafana health endpoint to determine the running version. Example: bash check_cve_2024_8118.sh https://grafana.internal:3000. No authentication required for the health endpoint.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_cve_2024_8118.sh — Detect Grafana versions vulnerable to CVE-2024-8118
# Usage: bash check_cve_2024_8118.sh <GRAFANA_BASE_URL>
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

set -euo pipefail

GRAFANA_URL="${1:-http://localhost:3000}"

VERSION=$(curl -sf "${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"

# Parse major.minor.patch
IFS='.' read -r MAJOR MINOR PATCH <<< "$(echo "$VERSION" | grep -oP '^[0-9]+\.[0-9]+\.[0-9]+')"

if [ -z "$MAJOR" ] || [ -z "$MINOR" ] || [ -z "$PATCH" ]; then
  echo "UNKNOWN — could not parse version string: $VERSION"
  exit 2
fi

# Vuln introduced in 8.5.0. Not affected below 8.5.0.
if [ "$MAJOR" -lt 8 ] || ([ "$MAJOR" -eq 8 ] && [ "$MINOR" -lt 5 ]); then
  echo "PATCHED — version $VERSION is below the affected range (8.5.0+)"
  exit 0
fi

# Fixed versions: 10.3.10, 10.4.9, 11.0.5, 11.1.6, 11.2.1
# Anything >= 11.3.0 is fixed (post-fix release train)
if [ "$MAJOR" -ge 12 ]; then
  echo "PATCHED — version $VERSION is above all affected ranges"
  exit 0
fi

if [ "$MAJOR" -eq 11 ]; then
  if [ "$MINOR" -ge 3 ]; then
    echo "PATCHED — $VERSION"; exit 0
  elif [ "$MINOR" -eq 2 ] && [ "$PATCH" -ge 1 ]; then
    echo "PATCHED — $VERSION (fixed in 11.2.1)"; exit 0
  elif [ "$MINOR" -eq 1 ] && [ "$PATCH" -ge 6 ]; then
    echo "PATCHED — $VERSION (fixed in 11.1.6)"; exit 0
  elif [ "$MINOR" -eq 0 ] && [ "$PATCH" -ge 5 ]; then
    echo "PATCHED — $VERSION (fixed in 11.0.5)"; exit 0
  else
    echo "VULNERABLE — $VERSION is in the affected range for CVE-2024-8118"; exit 1
  fi
fi

if [ "$MAJOR" -eq 10 ]; then
  if [ "$MINOR" -ge 5 ]; then
    echo "PATCHED — $VERSION is above affected 10.x ranges"; exit 0
  elif [ "$MINOR" -eq 4 ] && [ "$PATCH" -ge 9 ]; then
    echo "PATCHED — $VERSION (fixed in 10.4.9)"; exit 0
  elif [ "$MINOR" -eq 3 ] && [ "$PATCH" -ge 10 ]; then
    echo "PATCHED — $VERSION (fixed in 10.3.10)"; exit 0
  elif [ "$MINOR" -ge 3 ]; then
    echo "VULNERABLE — $VERSION is in the affected range for CVE-2024-8118"; exit 1
  else
    # 10.0-10.2 — these are between 8.5 and 10.3, so affected
    echo "VULNERABLE — $VERSION is in the affected range for CVE-2024-8118"; exit 1
  fi
fi

# Major 8 (>=8.5) or 9 — all affected, no backport fixes
if [ "$MAJOR" -eq 9 ] || ([ "$MAJOR" -eq 8 ] && [ "$MINOR" -ge 5 ]); then
  echo "VULNERABLE — $VERSION is in the affected range (8.5.0–9.x) with no fix available for this branch. Upgrade to 10.3.10+ or 11.x."
  exit 1
fi

echo "UNKNOWN — could not determine vulnerability status for $VERSION"
exit 2
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.