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.
3 steps from start to impact.
Obtain authenticated Grafana session with instance-write permission
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.- Valid Grafana credentials
- Account with
alert.instances.external:writeRBAC grant - Network access to the Grafana instance
- 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
Call the alert rule write API endpoint
/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.- External datasource must be configured and have alerting enabled
- Attacker knows the DatasourceUID and Namespace
- 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
Manipulate alert rules or exfiltrate data via notifications
- Notification channels must be configured and accessible
- Datasource must contain data of interest beyond what the attacker already has access to
- 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
The supporting signals.
| In-the-Wild Exploitation | None observed. No reports of active exploitation from any threat intelligence source. Not listed in CISA KEV catalog. |
|---|---|
| Proof-of-Concept | None 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 Score | 0.00583 (0.58%) — 46th percentile. Well below the threshold that would indicate meaningful exploit probability within 30 days. |
| KEV Status | Not listed. CVE-2024-8118 has not been added to the CISA Known Exploited Vulnerabilities catalog as of September 2026. |
| CVSS Vector | CVSS: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 Versions | Grafana 8.5.0 through 11.2.0 — spanning roughly 3 years of releases across 5 major version lines. |
| Fixed Versions | 11.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 Exposure | Shodan indexes ~46,000+ internet-facing Grafana instances globally. However, this CVE requires authenticated privileged access, so internet exposure alone does not constitute exploitability. |
| Disclosure Date | 2024-09-26 — disclosed and patched simultaneously by Grafana Labs. |
| Reporter | Not publicly attributed. Discovered and fixed internally by Grafana Labs. |
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.
What to do — in priority order.
- Audit and restrict alert.instances.external:write grants — Review Grafana RBAC role assignments and ensure
alert.instances.external:writeis granted only to users who also legitimately needalert.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. - 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. - 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. - 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.
- 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.
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.
#!/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 2What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.