← Back to Feed CACHED · 2026-07-23 03:27:00 · CACHE_KEY tenable:316482
tenable:316482 · CWE-73 · Disclosed 2026-03-25

Grafana Labs < 11

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

Your dashboards became a credential vault, and one buggy SQL expression opens it

Tenable plugin 316482 bundles the March/May 2026 Grafana security releases. The headline flaw is CVE-2026-27876 — a SQL Expressions arbitrary-file-write that chains through a Grafana Enterprise plugin into full RCE on the Grafana host, including SSH-key writes. The companion issue is CVE-2026-27880, an unauthenticated memory-exhaustion DoS via the OpenFeature endpoint. Additional bugs in the same release train (CVE-2026-28374/76/79/80/83, CVE-2026-33376–33381) cover public-dashboard secret leaks and missing protected-field authorization. Affected: Grafana 11.6.0–11.6.13, 12.0.0–12.1.9, 12.2.0–12.2.7, 12.3.0–12.3.5, 12.4.0–12.4.1. Fixed: 11.6.14+security-04, 12.1.10, 12.2.8+security-04, 12.3.6+security-04, 12.4.3+security-02, 13.0.1+security-01.

Grafana labels this HIGH (CVSS 9.1 on the RCE component) and that's a defensible call rather than an inflated one. The RCE requires *three* stacked prerequisites — the sqlExpressions feature toggle enabled, a Grafana Enterprise license with the vulnerable datasource plugin, and at least Viewer credentials on a datasource — but Grafana is a role multiplier: the box holds datasource credentials for Prometheus, Loki, cloud accounts, prod databases, and Kubernetes clusters. Fleet-wide, a compromised Grafana is a credential piñata, which is why we hold the verdict at HIGH rather than downgrading on friction alone.

"Grafana RCE is real but chain needs Enterprise plugin + feature toggle + creds; DoS is unauth but 'only' DoS. Keep at HIGH."
02 · The Attack Path

5 steps from start to impact.

STEP 01

Obtain Viewer-or-higher credentials on the Grafana instance

The RCE chain requires an authenticated session with datasource-query privileges. Anonymous org access, SSO auto-provisioning, or leaked API tokens satisfy this in many enterprises. Grafana instances behind SSO are still often provisioned to auto-grant Viewer on first login.
Conditions required:
  • Grafana reachable from attacker's network position
  • Viewer/Editor/Admin credential OR anonymous access enabled
Where this breaks in practice:
  • Most enterprise Grafanas sit behind SSO with restricted auto-provisioning
  • Anonymous access is off by default in modern deployments
Detection/coverage: Auth logs in grafana.log; SIEM correlation on new user + immediate datasource query
STEP 02

Confirm sqlExpressions toggle + Enterprise plugin present

The vulnerable code path lives behind the sqlExpressions feature toggle and requires a specific Grafana Enterprise datasource plugin to complete the chain. Attackers enumerate via /api/frontend/settings and /api/plugins. OSS-only deployments are not exploitable for RCE.
Conditions required:
  • sqlExpressions feature flag enabled
  • Grafana Enterprise + vulnerable datasource plugin installed
Where this breaks in practice:
  • OSS installs (majority of internet-exposed) lack the Enterprise plugin
  • Feature toggle is off by default in older 11.x lines
Detection/coverage: Config audit for feature_toggles.enable = sqlExpressions; plugin inventory via /api/plugins
STEP 03

Craft SQL expression that writes to arbitrary path

The attacker submits a query that abuses the Sqlyze driver load path or the AWS datasource config writer to drop attacker-controlled content — a rogue driver, an SSH authorized_keys file under the grafana user, or a datasource config that shells out on next load. Public PoC has not surfaced on GitHub as of this writing but the Grafana blog explicitly documents both primitives.
Conditions required:
  • Step 2 satisfied
  • Filesystem write reachable by grafana process UID
Where this breaks in practice:
  • Containerized deployments with read-only rootfs block the SSH-key path
  • AppArmor/SELinux profiles on distro packages constrain write locations
Detection/coverage: File integrity monitoring on /var/lib/grafana, /usr/share/grafana/plugins, ~grafana/.ssh
STEP 04

Trigger code execution and pivot to credential store

On next plugin load or SSH login as the grafana user, attacker code executes with the grafana service account. The immediate prize is grafana.db (SQLite) or the external DB — datasource credentials are encrypted with a static secret in grafana.ini that's also on-host. Cloud API keys, Prometheus basic-auth, and database creds fall out. Tooling: sqlite3 + custom decrypt scripts published against Grafana's securejsondata format.
Conditions required:
  • Step 3 landed
  • Access to grafana.db or configured external DB
Where this breaks in practice:
  • Vault-backed datasource secrets (Grafana OSS 10+ envvar refs) contain the blast
  • Read-only container filesystems limit persistence
Detection/coverage: EDR on unusual child processes of grafana-server; egress alerts on datasource-configured cloud endpoints from the Grafana host
STEP 05

Parallel/alternate: unauth DoS via OpenFeature (CVE-2026-27880)

For 12.1.0+ deployments, an unauthenticated attacker can POST unbounded input to the OpenFeature feature-flag validation endpoint and exhaust process memory, OOM-killing Grafana. No creds, no toggle, just reachability. This is the only unauthenticated primitive in the release.
Conditions required:
  • Grafana 12.1.0–12.4.1 reachable
Where this breaks in practice:
  • WAF request-size limits (>1MB body) blunt naive payloads
  • Autoscaling / systemd restart masks impact
Detection/coverage: OOM events in journald; 5xx spike on /api/featuremgmt/*
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo confirmed exploitation as of 2026-07-23; not on CISA KEV
Public PoCNone public on GitHub for CVE-2026-27876 chain; Grafana blog details primitives but withholds working exploit
EPSS~0.7% (percentile ~65) — moderate, reflects auth+toggle prerequisites
KEVNot listed
CVSS v3.1 (RCE)9.1 CRITICAL — AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H (vendor rates HIGH per blog title despite 9.1 score)
CVSS v3.1 (DoS)7.5 HIGH — AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Affected versions11.6.0–11.6.13, 12.0.0–12.1.9, 12.2.0–12.2.7, 12.3.0–12.3.5, 12.4.0–12.4.1
Fixed versions11.6.14+security-04, 12.1.10, 12.2.8+security-04, 12.3.6+security-04, 12.4.3+security-02, 13.0.1+security-01; Red Hat backport in RHSA-2026:7011
Exposure (Shodan/Censys)~110k Grafana instances internet-facing per Shodan HTTP title fingerprint; majority OSS, minority Enterprise-licensed
Disclosure / reporterGrafana security release 2026-03-25 (blog); Tenable plugin 316482; CVE-2026-27876 credited to internal Grafana security team
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to HIGH (8.1/10)

Verdict held at HIGH because the RCE chain requires the sqlExpressions feature toggle and an Enterprise plugin and Viewer credentials — three stacked prerequisites that narrow the exploitable population to a minority of installs. What prevents a downgrade to MEDIUM is the role multiplier: a compromised Grafana host is a credential vault for the observability plane (cloud API keys, prod DB creds, K8s tokens), so successful exploitation ends in lateral compromise, not just a dashboard defacement.

HIGH Affected/fixed version accuracy
HIGH Absence of public PoC / KEV status as of assessment date
MEDIUM Real-world share of Grafana Enterprise + sqlExpressions-enabled deployments

Why this verdict

  • Prerequisite stacking: RCE demands Enterprise license + vulnerable plugin + sqlExpressions toggle + Viewer creds. Each condition strips exploitable population — combined <10% of Grafana installs qualify.
  • Role multiplier: Grafana is *the* observability control plane; the process holds datasource creds for prod DBs, cloud accounts, Prometheus, Loki, K8s. RCE here = credential harvest, not a contained dashboard box. Floor stays HIGH.
  • Unauth surface exists but bounded: CVE-2026-27880 is a memory-exhaust DoS, not RCE — bad but recoverable behind autoscaling / systemd restart.
  • No active exploitation, no KEV, no public PoC — removes the CRITICAL upgrade pressure that would apply if a weaponized chain were circulating.
  • Widespread deployment: ~110k internet-facing instances per Shodan; even 5% Enterprise + toggle share equals thousands of exploitable targets, keeping the aggregate risk material.

Why not higher?

No public PoC, no KEV listing, no observed exploitation, and the RCE requires an Enterprise-licensed plugin plus a non-default feature toggle plus valid credentials. Under noisgate rules a CRITICAL floor requires either canonical high-value-role status alone with a working chain, active exploitation, or an unauthenticated primitive with RCE impact — none present here.

Why not lower?

Grafana's role as observability + datasource-credential store means a landed RCE cascades into cloud/DB/K8s credential theft, not just a defaced dashboard. The unauthenticated DoS primitive (CVE-2026-27880) also raises the aggregate floor above MEDIUM even for OSS-only deployments.

05 · Compensating Control

What to do — in priority order.

  1. Disable the sqlExpressions feature toggle — Edit grafana.ini or config-map and remove sqlExpressions from feature_toggles.enable. Restart the service. This alone kills the RCE primitive without touching the binary. Deploy within 30 days per noisgate HIGH mitigation SLA — or within hours if the instance is internet-facing.
  2. Restrict Grafana network exposure — Move all Grafana instances behind an SSO-authenticated reverse proxy (oauth2-proxy, Cloudflare Access, Tailscale). No Grafana should terminate TLS on the public internet. Blocks anonymous DoS and reduces credential-brute surface. Same 30-day window.
  3. Rotate all datasource credentials post-patch — Assume any pre-patch RCE would have exfiltrated the on-disk secret key + grafana.db. After upgrading, rotate every datasource credential, API key, and service-account token stored in Grafana. Complete within the 30-day mitigation window.
  4. Enforce request-size limits at the proxy — Add client_max_body_size 256k; (nginx) or equivalent Envoy/HAProxy rule for /api/featuremgmt/* and /api/frontend/settings to blunt CVE-2026-27880 memory-exhaust payloads until patched.
  5. Audit anonymous and auto-provisioned access — Set [auth.anonymous] enabled = false and disable auto_assign_org_role or set it to a no-datasource-access role. Removes the easiest path to Viewer-tier creds needed for the RCE chain.
What doesn't work
  • WAF signatures — the malicious SQL Expression payload is legitimate Grafana API traffic to a legitimate endpoint; no signature reliably discriminates.
  • Read-only container filesystem alone — helpful against SSH-key persistence but the AWS-datasource-config write primitive still executes code on next plugin load if the config dir is writable.
  • Downgrading to Grafana OSS — the DoS (CVE-2026-27880) and public-dashboard secret leaks still apply; only the Enterprise-plugin RCE goes away.
06 · Verification

Crowdsourced verification payload.

Run on the Grafana host itself with sudo (needs read on /etc/grafana/grafana.ini and the binary). Invoke: sudo bash check_grafana_316482.sh. Also usable against a remote instance with GRAFANA_URL=https://grafana.example.com API_TOKEN=glsa_xxx bash check_grafana_316482.sh for the version-only check.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# noisgate check for Tenable 316482 / Grafana security release 2026-03/05
# Exit codes: 0 PATCHED, 1 VULNERABLE, 2 UNKNOWN
set -u

STATUS="UNKNOWN"
DETAIL=""

version_lt() {
  # returns 0 if $1 < $2 (semver-ish, ignores +build metadata)
  [ "$1" = "$2" ] && return 1
  printf '%s\n%s\n' "$1" "$2" | sort -V -C && return 1 || return 0
}

get_version_local() {
  if command -v grafana-server >/dev/null 2>&1; then
    grafana-server -v 2>&1 | awk '/Version/ {print $2; exit}'
  elif [ -x /usr/sbin/grafana-server ]; then
    /usr/sbin/grafana-server -v 2>&1 | awk '/Version/ {print $2; exit}'
  fi
}

get_version_remote() {
  [ -z "${GRAFANA_URL:-}" ] && return 1
  curl -sk -H "Authorization: Bearer ${API_TOKEN:-}" \
    "${GRAFANA_URL%/}/api/health" | grep -oE '"version":"[^"]+"' | cut -d\" -f4
}

VER="$(get_version_local || true)"
[ -z "$VER" ] && VER="$(get_version_remote || true)"
VER="${VER%%+*}"  # strip +security-XX metadata

if [ -z "$VER" ]; then
  echo "UNKNOWN: could not determine Grafana version"
  exit 2
fi

# Fixed baselines per branch
case "$VER" in
  11.6.*)  FIX="11.6.14" ;;
  12.0.*|12.1.*) FIX="12.1.10" ;;
  12.2.*)  FIX="12.2.8" ;;
  12.3.*)  FIX="12.3.6" ;;
  12.4.*)  FIX="12.4.3" ;;
  13.0.*)  FIX="13.0.1" ;;
  *)       echo "UNKNOWN: unrecognized branch $VER"; exit 2 ;;
esac

if version_lt "$VER" "$FIX"; then
  STATUS="VULNERABLE"
  DETAIL="installed=$VER fixed>=$FIX"
else
  STATUS="PATCHED"
  DETAIL="installed=$VER meets fixed>=$FIX"
fi

# Extra: check if sqlExpressions toggle is enabled (elevates risk)
if [ -r /etc/grafana/grafana.ini ] && grep -Eiq '^[[:space:]]*enable[[:space:]]*=.*sqlExpressions' /etc/grafana/grafana.ini; then
  DETAIL="$DETAIL; sqlExpressions=ENABLED (RCE chain reachable if unpatched)"
fi

echo "$STATUS: $DETAIL"
case "$STATUS" in
  PATCHED)    exit 0 ;;
  VULNERABLE) exit 1 ;;
  *)          exit 2 ;;
esac
07 · Bottom Line

If you remember one thing.

TL;DR
Treat this as HIGH, not CRITICAL. Monday morning: (1) inventory every Grafana instance by branch and confirm whether sqlExpressions is enabled and whether Enterprise is licensed — that triage tells you which hosts need same-week attention vs which ride the normal cycle. (2) For any internet-facing Grafana or any Enterprise+sqlExpressions instance, apply the compensating controls (disable the toggle, put behind auth proxy) within the noisgate mitigation SLA of 30 days — sooner if exposed. (3) Roll the vendor patch to 11.6.14+security-04 / 12.2.8+security-04 / 12.4.3+security-02 / 13.0.1+security-01 (or the RHSA-2026:7011 backport) inside the noisgate remediation SLA of 180 days. (4) After patching, rotate every datasource credential stored in Grafana — assume pre-patch RCE would have exfiltrated the secret key.

Sources

  1. Grafana advisory — CVE-2026-27876 (sqlExpressions RCE)
  2. Grafana blog — Critical/High security release
  3. Grafana 11.6.14+security-04 release notes
  4. VulDB CVE-2026-28380 (Nessus 316482 / WID-SEC-2026-1546)
  5. Red Hat RHSA-2026:7011 backport
  6. Canadian Centre for Cyber Security AV26-285
  7. Grafana Security Advisories index
  8. Tenable Nessus plugin family (Grafana)
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.