← Back to Feed CACHED · 2026-07-23 03:14:16 · CACHE_KEY tenable:242132
tenable:242132 · CWE-285 · Disclosed 2025-06-02

Grafana Labs < 10

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

A trailing slash tricks Grafana's bouncer into waving through metric-only tourists

CVE-2025-3454 is an *improper authorization* bug in Grafana's datasource proxy API. Appending an extra / in the URL path defeats the proxy's route-matching allowlist, letting any authenticated Grafana user — even a bare Viewer — issue GET requests against Prometheus and Alertmanager datasources they were never granted. It affects Grafana 8.0 through 11.6.0 (fixed in 10.4.17+security-01, 11.2.8+security-01, 11.3.5+security-01, 11.4.3+security-01, 11.5.3+security-01, and 11.6.0+security-01, released 2 Jun 2025). No write, no code exec, no DoS — just read leakage of metric names, alert rules, and silences that the RBAC layer was supposed to hide.

Vendor MEDIUM (CVSS 5.0, PR:L / C:L / I:N / A:N) is defensible on paper because of the scope change, but in practitioner terms this is a LOW. It requires an authenticated account, is read-only, and the data typically exposed is telemetry that most orgs already treat as internal-general rather than crown-jewel. There is no KEV listing, no public exploit weaponization, and EPSS is essentially floor.

"Authenticated read-only bypass in Grafana's datasource proxy — vendor's MEDIUM is generous; this is backlog work, not a fire."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Obtain a low-privilege Grafana account

Attacker needs any authenticated session — Viewer role is enough. In practice this means a stolen session cookie, phished SSO credential, or a legitimate but over-scoped internal account. Anonymous access must be disabled or the attacker already has an account.
Conditions required:
  • Valid Grafana session
  • Network reachability to the Grafana instance
Where this breaks in practice:
  • Grafana is rarely internet-exposed in mature enterprises — usually behind SSO/VPN
  • Anonymous auth is off by default in modern deployments
Detection/coverage: Grafana audit log records login events; SSO IdP logs the auth. No specific IoC for this CVE at auth stage.
STEP 02

Enumerate datasources visible to the account

The attacker calls GET /api/datasources (or scrapes the UI) to list Prometheus/Alertmanager datasource UIDs. Any datasource the account can *see* — even without proxy permission — is a candidate. Tooling: curl, grafana-api python client, Burp.
Conditions required:
  • Any datasource UID reachable to the account
Where this breaks in practice:
  • RBAC in Grafana Enterprise can hide datasource UIDs from Viewers
Detection/coverage: High-cardinality /api/datasources/proxy/<uid>/... calls from a single session — easy WAF/access-log signature.
STEP 03

Send crafted proxy request with an extra slash

Attacker issues GET /api/datasources/proxy/<uid>//api/v1/query?query=... or //api/v2/alerts. The doubled slash bypasses Grafana's route allowlist match while the upstream Prometheus/Alertmanager still normalizes and serves the request. Weaponization: a 5-line curl loop; no public PoC repo of note as of assessment date.
Conditions required:
  • Vulnerable Grafana version (pre-security-01)
  • Datasource UID from step 2
  • Prometheus or Alertmanager on the other end of the proxy
Where this breaks in practice:
  • Only Prometheus/Alertmanager proxies are impacted — MSSQL, MySQL, Loki, Tempo proxies are not in the reported blast radius
  • GET only — no metric ingestion, silence write, or rule modification
Detection/coverage: Access logs will show // in the URI — trivially greppable. No native Grafana alert rule ships for this.
STEP 04

Exfiltrate metric names, labels, and alert state

Attacker paginates through /api/v1/label/__name__/values, /api/v1/series, and /api/v2/alerts. This yields the shape of the monitored estate — hostnames, service labels, cloud account IDs, and any firing/silenced alerts. Value depends on how sensitive metric cardinality is in that Prometheus.
Conditions required:
  • Prometheus/Alertmanager returns data on GET
Where this breaks in practice:
  • Impact is proportional to how much sensitive info leaks through label cardinality — often low
  • No lateral movement, no privilege escalation, no persistence primitive
Detection/coverage: Prometheus query-log (if enabled) shows unusual label/values and series calls; SIEM correlation on Grafana proxy log + Prom query log is high-signal.
03 · Intelligence Metadata

The supporting signals.

CVECVE-2025-3454
Vendor severity / scoreMEDIUM / CVSS 5.0 (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:N)
Tenable VPR1.2 (Low)
EPSS~0.04% (bottom decile) — no observed exploitation
CISA KEVNot listed
In-the-wildNo reports of exploitation as of 23 Jul 2026; no active campaigns
PoC statusNo weaponized public PoC repo. Reproduction is a one-line curl with // in the path — trivial but not packaged
Affected versionsGrafana 8.0 through 11.6.0 (all editions: OSS, Enterprise, Cloud)
Fixed versions10.4.17+security-01, 11.2.8+security-01, 11.3.5+security-01, 11.4.3+security-01, 11.5.3+security-01, 11.6.0+security-01 (2 Jun 2025)
Exposure dataShodan shows ~110k Grafana instances internet-exposed globally; the *authenticated* attack surface is a subset that requires a valid account
ReporterExternal contributor via pull-request review (credited by Grafana Labs)
Disclosed2 Jun 2025 alongside CVE-2025-3260 and CVE-2025-2703
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to LOW (3.5/10)

The single most decisive factor is that this is an authenticated, read-only bypass whose payload is telemetry metadata — not credentials, not code execution, not data-tier records. Blast radius is bounded to whatever Prometheus/Alertmanager exposes over GET, which in the overwhelming majority of deployments is infrastructure metrics rather than regulated data.

HIGH Technical impact assessment (read-only, GET-only, Prom/Alertmanager only)
HIGH Absence of KEV listing / active exploitation as of Jul 2026
MEDIUM Data-sensitivity assumption — some orgs put PII-ish labels in Prometheus

Why this verdict

  • Authentication required (PR:L): every step in the chain assumes the attacker already holds a Grafana session. That collapses the addressable population from 'internet-random' to 'insider or credential-thief already past IdP/MFA'.
  • Read-only, GET-only: no write to silences, no rule mutation, no metric ingestion, no RCE, no DoS. Integrity and availability sub-scores are zero for a reason.
  • Narrow datasource scope: only Prometheus and Alertmanager proxies are affected. SQL, Loki, Tempo, InfluxDB, CloudWatch, and other proxy targets are out of scope.
  • Role multiplier — typical Grafana role (LOB monitoring dashboard): chain succeeds; blast radius = leak of metric names/labels/alert state. Impact is *reconnaissance-grade*, not compromise-grade.
  • Role multiplier — high-value Grafana role (SRE control plane exposing Prometheus with sensitive labels, e.g. tenant IDs, customer names, PII in labels): chain succeeds; blast radius = intelligence leakage that could aid a follow-on targeted attack. Still not fleet-scale, not domain takeover, not supply-chain — floor stays at LOW/MEDIUM, not HIGH. Grafana is *not* a canonical high-value-role component (it's not an IdP, hypervisor, PAM, backup, or kernel-mode agent), so the CRITICAL floor does not apply.
  • No KEV, no active exploitation, EPSS near floor: none of the amplifiers that would override the friction-driven downgrade are present.

Why not higher?

MEDIUM would require either a wider datasource scope (write, or non-Prom datasources), or an unauthenticated variant. Neither exists. HIGH would require impact on integrity/availability or role-multiplier evidence that Grafana routinely sits in a domain-takeover-adjacent position — it does not.

Why not lower?

IGNORE is inappropriate because there *is* real information disclosure — metric labels frequently encode tenant identifiers, hostnames, and cloud account IDs that are useful to an attacker doing target selection. It belongs in the backlog, not the trash.

05 · Compensating Control

What to do — in priority order.

  1. Enforce SSO + MFA on all Grafana logins and disable anonymous access — Removes the *bring-your-own-account* variant. Verify [auth.anonymous] enabled = false and that [auth.basic] is off in favor of your IdP. As a LOW verdict there is no noisgate mitigation SLA — bundle this into your normal identity hygiene cadence rather than treating it as an emergency.
  2. Add a WAF / reverse-proxy rule normalizing or rejecting // in /api/datasources/proxy/* paths — A single nginx merge_slashes on; or an Envoy normalize_path directive collapses the double slash before Grafana sees it. Deploy alongside your next regular WAF ruleset push — no mitigation SLA applies at LOW.
  3. Audit Prometheus label cardinality for sensitive fields — If your Prometheus labels contain tenant IDs, customer names, or PII, the impact of this bug (and many future ones) is materially higher. Add this to Q3 backlog and treat as ongoing hygiene.
  4. Schedule the security-01 patch train in the next regular Grafana maintenance window — Ride the noisgate remediation SLA of ≤ 365 days. The upgrade to 10.4.17+security-01 / 11.x.y+security-01 is a routine minor bump with no schema or plugin-API breaking changes.
What doesn't work
  • Network-level blocking of Grafana — the bug is triggered by an authenticated user, so a public/private split doesn't reduce the internal-attacker case.
  • Grafana RBAC datasource permissions alone — the whole point of the CVE is that the proxy layer bypasses RBAC when the URL has a stray slash.
  • Turning off Alertmanager UI — the bypass targets the *proxy path*, not the UI; the Alertmanager datasource itself must be removed or the version patched.
  • CSP / browser-side mitigations — this is a server-side auth check bug; browser policy is irrelevant.
06 · Verification

Crowdsourced verification payload.

Run on any host with network access to the Grafana instance (auditor workstation is fine). No credentials required — this checks the advertised build version via the public /api/health endpoint. Invoke: ./check_grafana_3454.sh https://grafana.corp.example.com. Exit 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# noisgate verification for CVE-2025-3454 (Grafana datasource proxy auth bypass)
# Usage: ./check_grafana_3454.sh <grafana_base_url>
set -u
URL="${1:-}"
if [[ -z "$URL" ]]; then
  echo "Usage: $0 <grafana_base_url>" >&2
  exit 2
fi

JSON=$(curl -sk --max-time 10 "${URL%/}/api/health") || {
  echo "UNKNOWN: could not reach $URL/api/health"; exit 2; }

VER=$(echo "$JSON" | grep -oE '"version"[[:space:]]*:[[:space:]]*"[^"]+"' | sed -E 's/.*"([^"]+)"$/\1/')
if [[ -z "$VER" ]]; then echo "UNKNOWN: no version in /api/health response"; exit 2; fi

echo "Detected Grafana version: $VER"

# Strip metadata; keep base semver and security tag if present
BASE=$(echo "$VER" | awk -F'[+ -]' '{print $1}')
SEC_TAG=$(echo "$VER" | grep -oE 'security-[0-9]+' | head -1)

IFS='.' read -r MAJ MIN PAT <<<"$BASE"

fixed() { echo "PATCHED: $VER contains security fix for CVE-2025-3454"; exit 0; }
vuln()  { echo "VULNERABLE: $VER is below the +security-01 fix train for CVE-2025-3454"; exit 1; }

# Any 12.x is post-fix
if (( MAJ >= 12 )); then fixed; fi

# Require security-01 tag on the affected minor lines
if (( MAJ == 11 )); then
  case "$MIN" in
    2)  [[ -n "$SEC_TAG" && "$PAT" -ge 8 ]] && fixed || vuln ;;
    3)  [[ -n "$SEC_TAG" && "$PAT" -ge 5 ]] && fixed || vuln ;;
    4)  [[ -n "$SEC_TAG" && "$PAT" -ge 3 ]] && fixed || vuln ;;
    5)  [[ -n "$SEC_TAG" && "$PAT" -ge 3 ]] && fixed || vuln ;;
    6)  [[ -n "$SEC_TAG" ]] && fixed || vuln ;;
    7|8|9|10|11|12) fixed ;;  # 11.7+ ships fix inline
    *) vuln ;;
  esac
fi

if (( MAJ == 10 )); then
  if (( MIN == 4 )) && [[ -n "$SEC_TAG" && "$PAT" -ge 17 ]]; then fixed; else vuln; fi
fi

if (( MAJ < 10 )); then vuln; fi

echo "UNKNOWN: version $VER did not match any known branch"; exit 2
07 · Bottom Line

If you remember one thing.

TL;DR
Treat this as backlog hygiene, not an incident. Monday morning: confirm anonymous auth is off and SSO+MFA is enforced on Grafana, drop a merge_slashes on; (or equivalent) at your reverse proxy to collapse // before Grafana sees it, and add the +security-01 bump to the next scheduled Grafana maintenance window. Per the noisgate mitigation SLA, LOW carries no mitigation deadline — skip straight to the noisgate remediation SLA of ≤ 365 days for the actual upgrade. Escalate only if your Prometheus labels contain regulated data (tenant IDs, PII, customer identifiers), in which case bump the compensating-control work to the front of the next sprint.

Sources

  1. Tenable Nessus plugin 242132
  2. Grafana Labs security release blog (CVE-2025-3260, 2703, 3454)
  3. Grafana Security Advisories index
  4. NVD — CVE-2025-3454
  5. Canadian Centre for Cyber Security AV26-285
  6. Grafana datasource proxy documentation
  7. CISA KEV catalog (search: CVE-2025-3454)
  8. FIRST EPSS lookup
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.