The receipt paper left facing the customer — a webhook URL printed on the wrong side of the RBAC boundary
Grafana's Alerting subsystem lets you configure contact points — outbound webhooks that fire when an alert triggers. The DingDing integration (a chat platform used mostly by organizations with China/APAC operations) stores its webhook URL in the contact point config. Because that URL field was not marked as secure, it was returned in cleartext to any user with Viewer role who queried the alerting configuration API. The webhook URL typically contains an access_token query parameter that, if leaked, lets an attacker post arbitrary messages into the target DingDing group. Affected: Grafana <10.4.19, <11.2.10, <11.3.7, <11.4.5, <11.5.5, <11.6.2, <12.0.1. Fixed in the +security-01 suffixed builds.
Grafana labeled this MEDIUM (4.3) with vector AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N. That's a fair ceiling but overstates the practical impact for most fleets. The bug requires an authenticated Viewer account, the affected integration is DingDing specifically (not Slack/Teams/PagerDuty/Opsgenie), the leaked artifact is a chat webhook — not credentials into your infra — and the worst-case abuse is spamming or phishing a chat channel. For enterprises that don't use DingDing this is a non-event; for those that do, it's a LOW with a documentation footnote about rotating the webhook token.
3 steps from start to impact.
Obtain a Grafana Viewer account
- Grafana instance is reachable by the attacker
- Attacker has valid Viewer+ credentials or a session cookie
- Most enterprise Grafana instances are internal-only or behind SSO/VPN
- Viewer-role accounts are provisioned to trusted staff
- MFA on the IdP blocks credential-stuffing at the front door
viewer login eventsQuery the alerting contact-points API
GET /api/v1/provisioning/contact-points (or navigates the Alerting UI). Because the DingDing url field was not flagged as secret, the response includes the full webhook URL — typically https://oapi.dingtalk.com/robot/send?access_token=<token>. Standard curl with the session cookie is sufficient; no exploit tooling required.- Target org actually uses DingDing as a contact point
- Alerting is enabled on the instance
- DingDing usage is rare outside APAC-facing orgs — irrelevant for the majority of Western enterprises
- Some orgs use Slack/Teams/Opsgenie exclusively and never touch DingDing
/api/v1/provisioning/contact-points; unusual Viewer API calls stand out in SIEMAbuse the leaked webhook
access_token. Realistic abuse: social-engineering payloads that look like legitimate Grafana alerts, spam, or disruption of the alert channel to bury real alerts during a follow-on attack. There is no path from this webhook to Grafana admin, dashboards, datasources, or the host OS.- Attacker can egress to
oapi.dingtalk.com - The target DingDing group contains humans who trust alert messages
- Chat webhooks are one-way — cannot read messages back
- DingDing keyword/IP allowlists on the robot may reject rogue posts
- Rotating the webhook token invalidates the leaked URL immediately
The supporting signals.
| In-the-wild exploitation | None observed. Not listed in CISA KEV. No public campaigns reference this CVE. |
|---|---|
| Public PoC | No standalone PoC repo. The fix commit in grafana/grafana implicitly documents the trigger (mark webhook URL as secure). |
| EPSS | Well below the 1st percentile — this is not a mass-exploitation candidate. |
| KEV status | Not on KEV. |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N → 4.3 MEDIUM. PR:L is doing most of the work; impact is confidentiality-only. |
| Affected versions | Grafana <10.4.19, <11.2.10, <11.3.7, <11.4.5, <11.5.5, <11.6.2, <12.0.1 — LTS and current branches. |
| Fixed versions | 10.4.19+security-01, 11.2.10+security-01, 11.3.7+security-01, 11.4.5+security-01, 11.5.5+security-01, 11.6.2+security-01, 12.0.1+security-01. RHEL/Fedora backports tracked in Red Hat Bugzilla 2374548. |
| Exposure population | Shodan shows ~110k internet-facing Grafana instances. DingDing contact-point usage is a small single-digit percentage — realistically only APAC-facing tenants. Effective exposed population is a rounding error. |
| Disclosure date | 2025-07-17 (Grafana Labs security advisory). |
| Reporter | Reported through Grafana Labs' security channel; researcher not publicly credited in the advisory. |
noisgate verdict.
The decisive factor is scope: the leak is limited to one specific and niche integration (DingDing) and requires an authenticated Viewer account, so the reachable population and abuse ceiling are both small. Confidentiality impact stops at a chat webhook token — no path to Grafana admin, datasources, dashboards, or host.
Why this verdict
- Authenticated precondition: requires a valid Viewer session — no unauthenticated internet path exists, immediately narrowing the attacker population to insiders and post-initial-access adversaries.
- Feature-specific: only fires if DingDing is actually configured as a contact point. Slack/Teams/PagerDuty/Opsgenie/Webhook users are unaffected. Most Western enterprises will not have DingDing configured.
- Blast radius is a chat webhook: the leaked artifact posts messages to one DingDing group. It does not grant access to Grafana admin, dashboards, datasources, cloud credentials, or the host. There is no lateral pivot.
- Role multiplier — Grafana Alerting instance: the affected component is a monitoring UI, not identity/PKI/hypervisor/CI-CD/backup/edge/kernel-agent infrastructure. Even in the worst high-value deployment (SRE central alerting), the chain caps at chat-channel abuse. No floor is triggered.
- No exploitation signal: EPSS is negligible, KEV silent, no PoC repos, no reported campaigns.
Why not higher?
MEDIUM would require either an unauthenticated path or a more damaging secret (datasource credentials, service-account tokens). The leak is bounded to DingDing webhook URLs and requires Viewer role, which is not enough to justify the vendor's 4.3.
Why not lower?
Not IGNORE because organizations that do use DingDing genuinely expose an API token to any Viewer, and rotating it takes real coordination. It's LOW rather than IGNORE so it lands in a hygiene queue rather than being written off.
What to do — in priority order.
- Inventory DingDing contact points across all Grafana tenants — Run
GET /api/v1/provisioning/contact-pointsas admin on every instance and grep fordingding. If none are configured, this CVE is inapplicable to your fleet — document and close. Complete inventory within the standard backlog window; there is no noisgate mitigation SLA for LOW. - Rotate DingDing webhook tokens where the integration is in use — Generate a new DingDing robot access_token, update the Grafana contact point, and revoke the old token in the DingDing admin console. This defangs any URL already harvested by a Viewer. Do this alongside the version upgrade.
- Audit Viewer-role accounts and Viewer API access logs — Pull 90 days of
/api/v1/provisioning/contact-pointsreads by Viewer accounts; any Viewer hitting provisioning endpoints is anomalous and worth a look. Feed into your existing SIEM detections. - Upgrade Grafana to the
+security-01build on your branch — The fix marks the DingDingurlfield assecure, so it is redacted from Viewer-facing API responses. Use your normal Grafana upgrade cadence — no expedited change window needed. - Constrain Viewer role via team-scoped folder permissions — If Viewer must access alert rules, scope them to specific folders that do not contain the DingDing contact point. Reduces the blast radius of any similar future disclosure bug.
- WAF rules blocking
/api/v1/provisioning/contact-points— the endpoint is legitimately used by admins and Terraform; blocking it breaks IaC pipelines and Viewers can still trigger the leak through the Alerting UI. - Network segmentation of Grafana — the attacker already has an authenticated Viewer session, so they are inside your perimeter by definition. Segmentation does not help.
- Secret scanning on the leaked URL — the DingDing webhook token is not a formatted secret that GitHub/GitLab scanners recognize; you cannot rely on scanner catch-rate.
Crowdsourced verification payload.
Run on an auditor workstation with network reachability to the Grafana API. Requires an admin API token to enumerate contact points. Invoke as GRAFANA_URL=https://grafana.corp GRAFANA_TOKEN=glsa_xxx ./check-cve-2025-3415.sh. Outputs VULNERABLE if Grafana version is below the fix AND a DingDing contact point exists, PATCHED if on a +security-01 build, UNKNOWN otherwise.
#!/usr/bin/env bash
# check-cve-2025-3415.sh — assess Grafana exposure to CVE-2025-3415
# Usage: GRAFANA_URL=https://grafana.corp GRAFANA_TOKEN=glsa_xxx ./check-cve-2025-3415.sh
set -euo pipefail
: "${GRAFANA_URL:?set GRAFANA_URL}"
: "${GRAFANA_TOKEN:?set GRAFANA_TOKEN (admin service account token)}"
AUTH=(-H "Authorization: Bearer ${GRAFANA_TOKEN}" -H "Accept: application/json")
# 1. Fetch version
VER_JSON=$(curl -fsS "${AUTH[@]}" "${GRAFANA_URL%/}/api/health" || true)
VERSION=$(printf '%s' "$VER_JSON" | sed -n 's/.*"version"[^"]*"\([^"]*\)".*/\1/p')
if [[ -z "$VERSION" ]]; then
echo "UNKNOWN: could not read /api/health"; exit 2
fi
echo "Detected Grafana version: $VERSION"
# 2. Check if patched build (looks for +security-01 or newer patch stream)
if printf '%s' "$VERSION" | grep -qE '\+security-0[1-9]'; then
PATCHED_BUILD=1
else
PATCHED_BUILD=0
fi
# 3. Enumerate contact points and look for DingDing
CP_JSON=$(curl -fsS "${AUTH[@]}" "${GRAFANA_URL%/}/api/v1/provisioning/contact-points" || echo '[]')
if printf '%s' "$CP_JSON" | grep -qiE '"type"[[:space:]]*:[[:space:]]*"dingding"'; then
HAS_DINGDING=1
else
HAS_DINGDING=0
fi
# 4. Verdict
if [[ $PATCHED_BUILD -eq 1 ]]; then
echo "PATCHED: running $VERSION (contains +security-01 fix)"
exit 0
fi
if [[ $HAS_DINGDING -eq 0 ]]; then
echo "UNKNOWN: version $VERSION is pre-fix but no DingDing contact point configured — CVE not applicable to this instance"
exit 0
fi
echo "VULNERABLE: version $VERSION is pre-fix AND DingDing contact point is configured — Viewer role can read the webhook URL"
exit 1
If you remember one thing.
access_token and upgrade to the +security-01 build. Per the noisgate mitigation SLA for LOW there is no mitigation deadline — go straight to the noisgate remediation SLA and fold the Grafana upgrade into your normal patch cadence (backlog hygiene, no dedicated change window). Do not divert capacity from CRITICAL/HIGH work to accelerate this.Sources
- Grafana Labs security advisory — CVE-2025-3415
- Grafana blog — Medium severity security release for CVE-2025-3415
- NVD — CVE-2025-3415
- Tenable Nessus plugin 242626
- Wiz vulnerability database — CVE-2025-3415
- Red Hat Bugzilla 2374548 (Fedora backport tracking)
- Broadcom / VMware advisory for Grafana in Healthwatch
- SecurityOnline write-up
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.