Skip to content

Our research

CVE-2026-15583: SSRF in the Grafana MCP Server Explained

By Lucas Weber, CyberSec42 · Updated 28 Oct 2026

Schematic of an MCP server sitting between an AI client and a target system

CVE-2026-15583 is a server-side request forgery (SSRF) of the confused-deputy kind in the open source Grafana MCP Server (mcp-grafana): by setting the X-Grafana-URL request header, an unauthenticated caller could choose the host to which the server sent its environment-configured Grafana credentials. The CVE record rates it CVSS 8.6 (high) and lists every version up to and including 0.17.1 as affected. It is fixed in version 0.17.2, released on 13 July 2026, and the CVE record credits CyberSec42 as the finder.

In short.

Background

What an MCP server is and why it holds credentials.

Go to section

The vulnerability

The mechanism in plain words and in detail.

Go to section

Who was affected

Versions and deployment modes.

Go to section

The fix

What changed and what operators should do.

Go to section

Timeline

Publicly documented dates only.

Go to section

The underlying pattern

Confused deputies in MCP servers.

Go to section

Key facts

ItemDetail
IdentifiersCVE-2026-15583, GHSA-7cfp-pmw3-4j7r
ProductGrafana MCP Server (grafana/mcp-grafana)
ClassSSRF, confused deputy; CWE-610 “Externally Controlled Reference to a Resource in Another Sphere”
SeverityCVSS 3.1: 8.6, high (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N)
Affectedall versions up to and including 0.17.1
Fixed0.17.2, released 13 July 2026
Published15 July 2026, with Grafana Labs as the CVE Numbering Authority (CNA)
Credit“cybersec42” as finder in the CVE record

Background: what an MCP server is and why it holds credentials

The Model Context Protocol (MCP) is an open standard that lets AI assistants call tools and data sources. An MCP server sits in the middle: it accepts tool calls from an AI client and turns them into calls against a target system. According to its documentation, the Grafana MCP Server gives AI assistants access to a Grafana instance, so they can query metrics and logs, search and manage dashboards, manage alert rules, and work with features such as Grafana Incident and Sift.

To do any of that, the server needs Grafana credentials. Operators typically put the instance URL and a service account token into environment variables (GRAFANA_URL and GRAFANA_SERVICE_ACCOUNT_TOKEN, formerly GRAFANA_API_KEY). From then on the server acts with that token's privileges, on behalf of anyone who can reach it. That is what makes an MCP server an attractive target: it is a deputy with authority. General hardening advice lives in our guide to securing MCP servers; this article covers one specific case.

The deployment mode, which MCP calls the transport, is key to understanding the issue. The Grafana MCP Server supports three: stdio (the default, where the AI client launches the server as a local process), plus sse and streamable-http (where the server runs as a network service and accepts HTTP requests). On the HTTP transports the server can also read configuration per request from headers, including X-Grafana-URL for the target address and dedicated headers for a token. The source code describes this as support for multi-tenant scenarios, which is a useful feature. The vulnerability sat in how those headers interacted with the environment-configured credentials.

The vulnerability

In plain words

Picture a courier who collects documents from your bank using your company ID. Any client may give the courier a different address, in case the bank has several branches. But the courier never checks whether the new address still belongs to your bank, and shows your company ID at every door. Anyone who gives the address of their own office gets to see your ID and can copy it.

That is how the Grafana MCP Server behaved up to version 0.17.1. The ID is the service account token, the address is the X-Grafana-URL header.

In detail

The server resolved the target URL and the credentials independently, and each had its own fallback to the environment. The commit message of the fix describes it the same way. If a request carried X-Grafana-URL but no token header of its own, the server took the URL from the header and the token from the environment. The same applied to basic auth and to extra headers the operator had configured in the environment. Such headers can carry secrets themselves, an Authorization header for example. The next call to “Grafana” therefore went, together with the operator's credentials, to a host the caller had picked.

The term confused deputy describes exactly this situation: a service with authority (the deputy) is tricked by someone without that authority into using it for someone else's purposes. The CVE record also states that the same mechanism enables SSRF against arbitrary internal services, including cloud metadata endpoints. Grafana's advisory calls it “credentialed SSRF”, meaning requests to internal targets that also carry credentials.

Reading the vector: PR:N and UI:N mean neither a login nor any user action was needed. S:C (scope changed) means, per the CVSS specification, that the impact reaches beyond the vulnerable component. The MCP server was vulnerable, while the impact lands on the Grafana instance whose token could leak. C:H stands for the loss of confidentiality; according to the vector, integrity and availability of the server itself are not affected. We recomputed the 8.6 base score from the formula in the specification.

Schematic flow

Caller sets X-Grafana-URL MCP server token from env Grafana intended target Foreign host receives the token 0.17.2+: only here up to 0.17.1
Up to 0.17.1 the caller could redirect the target and the environment token went along. From 0.17.2 the credentials are bound to the configured Grafana URL.
  1. The operator runs mcp-grafana with an HTTP transport. The URL and token of their own Grafana instance sit in environment variables.
  2. A caller who can reach the HTTP endpoint sends an MCP request with X-Grafana-URL pointing at a host of their choice, without a token of their own.
  3. The server takes the URL from the header and fills in the credentials from the environment.
  4. The next tool call goes to the foreign host with the token attached, and that host can record it.
  5. With the token, the real Grafana instance can be called directly, within the privileges of the service account.

We deliberately publish no exploit code. The description is enough to assess your own deployment and to follow the fix.

Who was affected

The CVE record names a single product, the Grafana MCP Server, in all versions up to and including 0.17.1. Grafana itself is not listed as vulnerable, but the Grafana instance is where a leaked token takes effect. According to the fix commit, the behaviour affected the HTTP and SSE transports. In the 0.17.1 source code, stdio mode reads its configuration from the environment only, not from request headers.

Deployment modeAssessment up to 0.17.1
stdio (default, local process)Request headers are not read, so the path described here does not exist
sse or streamable-http, credentials set in the environmentAffected. Exploitable by anyone who can reach the HTTP endpoint, without authentication per the CVE record
sse or streamable-http, no credentials in the environmentNothing was there that could have followed the caller's target

The actual risk in a given deployment depends on who could reach the HTTP endpoint (only the local machine, an internal network or the internet) and on the privileges of the service account in Grafana.

The fix and what operators should do now

What changed in 0.17.2

The fix binds environment-configured credentials to the Grafana URL configured in the environment. If X-Grafana-URL points at a different instance, the server no longer attaches the service account token, the deprecated API key, basic auth or extra headers from the environment. The caller has to supply their own credentials for that URL. Both URLs are normalised before they are compared. Headers the operator has explicitly chosen to forward (GRAFANA_FORWARD_HEADERS) are still passed on. Requests without X-Grafana-URL, or with the configured URL, behave as before. The fix also adds tests that cover exactly these cases.

It is a structural fix: rather than blocking individual targets, the authority is now tied to the target. Multi-instance support stays intact.

Recommendations for operators

The following steps are our recommendations, not vendor requirements.

StepAction
1. Check the versionUpgrade to 0.17.2 or later. Version 0.17.1 is still affected according to the CVE record, and the fix only ships in the repository from 0.17.2.
2. Rotate the tokenIf you ran an HTTP transport with environment credentials and the endpoint was reachable by callers you do not fully trust: issue a new service account token and revoke the old one. The same goes for basic auth passwords and secrets in extra headers.
3. Limit privilegesGive the service account only the roles the enabled tools actually need.
4. Shield the endpointDo not expose the HTTP endpoint unprotected. Bind it to localhost or an internal network and put authentication in front of it.
5. Restrict outbound trafficAllow the server to connect only to your own Grafana instance. A future misdirection then leads nowhere, and metadata endpoints stay out of reach.
6. Review logsIf your reverse proxy logs request headers, look for requests whose X-Grafana-URL differs from the configured URL.

Timeline

Only dates that can be verified from public sources are listed.

DateEventSource
7 Jul 2026Release 0.17.1, the last affected versionGitHub release v0.17.1
13 Jul 2026CVE ID reserved by Grafana Labs as CNACVE record
13 Jul 2026Fix merged (pull request #995), release 0.17.2GitHub
15 Jul 2026CVE record, Grafana advisory and GHSA-7cfp-pmw3-4j7r publishedCVE.org, grafana.com, GitHub
15 Jul 2026CISA adds an SSVC assessment to the record: exploitation “none”, automatable “yes”, technical impact “partial”CVE record (CISA ADP)

The fixed version was therefore available two days before the vulnerability was described publicly. The date of the original report is not publicly documented and is therefore not listed.

The underlying pattern: confused deputies in MCP servers

Behind CVE-2026-15583 lies a pattern that comes naturally to MCP servers. Many servers hold the operator's credentials and at the same time let callers override parts of the configuration per request, because that is convenient for multiple tenants or instances. It turns dangerous as soon as target and credentials are resolved separately and each half falls back to a default on its own. The caller then picks the target, and the operator supplies the credentials.

In our walkthrough of the OWASP MCP Top 10, this case touches three classes: the confused deputy from class 1, SSRF from class 5, and credentials forwarded unchecked to a foreign destination from class 7. For developers of MCP servers it boils down to four rules:

For operators, the flip side applies: an MCP server with an HTTP transport is a network service holding your credentials. It deserves the same treatment as any other API with secrets, meaning authentication, least privilege and restricted outbound connections.

Thanks to the Grafana security team

We thank the Grafana Labs security team for the coordinated collaboration. The report was submitted confidentially through Grafana's bug bounty programme, and the CVE record lists “BUG_BOUNTY” as its source. Grafana Labs assigned the CVE as CNA, shipped the fixed version ahead of publication, and published the advisory and the CVE record crediting CyberSec42. This is how coordinated disclosure should work: operators were able to upgrade before the details became public.

Does your MCP server hold credentials it should never hand out?

We test MCP servers and AI agents within a scope agreed in writing: where credentials can flow, which targets a caller can influence, how the transports are secured and what a tool call can actually reach. Every finding comes with reproducible evidence and a concrete fix. Learn more about AI pentesting & MCP security.

Request an AI pentest

CyberSec42 is an independent technical security assessment, not an accredited certification body, and does not provide legal advice. CyberSec42 is not affiliated with Grafana Labs.

Frequently asked questions

What is CVE-2026-15583?

A confused-deputy SSRF vulnerability in the Grafana MCP Server. Through the X-Grafana-URL header, an unauthenticated caller could make the server send its environment-configured Grafana credentials to a host of the caller's choice. The CVE record rates it CVSS 8.6 (high).

Which versions of the Grafana MCP Server are affected?

According to the CVE record, all versions up to and including 0.17.1. The issue is fixed in 0.17.2, released on 13 July 2026. Upgrade to 0.17.2 or later.

Is Grafana itself affected?

The CVE record lists only the Grafana MCP Server as the affected product. The Grafana instance is affected once a leaked token is used against it, within the privileges of the corresponding service account.

Am I affected if I run the server over stdio?

According to the fix commit, the behaviour affected the HTTP and SSE transports. In stdio mode the server reads its configuration from the environment, not from request headers. You should still upgrade, since the deployment mode may change later.

Do I need to rotate my service account token?

We recommend it if you ran an HTTP transport with environment credentials and the endpoint was reachable by callers you do not fully trust. A new token costs little, while a leaked one stays valid until it is revoked.

Has the vulnerability been actively exploited?

The CISA SSVC assessment in the CVE record, dated 15 July 2026, lists exploitation as “none”. The public sources make no statement about exploitation after that date.

Further reading

Sources