Blog

min read

Valid, But Never Issued: Session Spoofing and SSRF in Grafana MCP

By

Ariel Fogel

and

August 31, 2026

min read

Executive summary

Grafana is an open-source observability platform that brings production metrics, logs, and traces into dashboards and alerts. Grafana Labs reports more than 1.5 million active installations and 25 million global users, reflecting its broad adoption across modern enterprise  infrastructure. Its dashboards and data sources can reveal internal architecture, deployment state, production incidents, and the health of critical systems. Because Grafana commonly centralizes operational telemetry and connects to data sources, the implications of the service’s compromise can range from exposure of sensitive operational data, to changes that disrupt monitoring or, where connected systems grant additional privilege, broader infrastructure compromise.

Pillar Security identified two security issues that composed into a critical severity killchain in Grafana MCP, which has more than 1.9 million cumulative Docker Hub downloads to date. In affected MCP server deployments, an unauthenticated attacker could interact with the Grafana service and data, and use the server as a bridge to systems reachable from the server’s network position, potentially beyond the caller’s reach.

The first issue let reachable callers invoke MCP tools without authentication, meaning they could make requests using the Grafana service account configured on the server. To address this issue, Grafana shipped optional bearer-token protection in v1.1.0.

The second issue let callers direct the server’s HTTP-request tool to a destination of their choice, including internal services and cloud metadata endpoints. Grafana protected its service-account token from being sent to a foreign destination, but the server still made the request and returned the response. This critical SSRF vulnerability was assigned CVE-2026-19516, with a CVSS score of 9.1.

Though discovered in the same engagement, the two issues required separate fixes. Authentication controlled who could use the MCP server; destination controls limit where that server can be directed to connect.  Together, they show a core risk of MCP: the server acts with its own credentials and network access, not the caller’s. It must therefore establish who is making the request, what they are allowed to do, and which systems it may reach on their behalf.

Part one: The appearance of an authentication boundary

In our recent Dolt MCP research, we found a server that appeared to reject unauthenticated requests but still dispatched their tool calls. One root issue behind this bug was that the MCP server's default behavior only performed validation on the format of the session-ID token rather than authenticating the session itself.

That result prompted us to examine a related question across other MCP server designs: when a server appears to gate access on a protocol value, does that value actually establish an authenticated caller?

We approached Grafana MCP with two questions:

  1. Did the server reject malformed or missing protocol state?
  2. Can an untrusted caller still reach an authority-bearing tool?

MCP’s HTTP transports use session identifiers to associate requests with server-side protocol state. That is a useful state-management feature. A careful observer might nevertheless mistake session validation for authentication, particularly when the tools behind the session boundary can expose valuable operational data or perform high-impact actions. While a session gate can look like a meaningful boundary, it does not hold unless the server also establishes who is presenting the session and whether that caller may use it.

In the affected Grafana MCP server releases, a reachable caller could generate a value in the expected session format:

Session ID Block
None
Mcp-Session-Id: mcp-session-e6576170-fa60-4cad-be9c-d6f809d75ce4

Despite supplying no credential, the server accepted tools/list call and returned the enabled tool catalog in addition to accepting tools/call requests using the same locally generated value. The caller could also invoke grafana_api_request, which made requests to Grafana using the service-account token stored in the MCP server environment. In our controlled environment, the Grafana canary recorded the request with the MCP server’s configured bearer token, even though the remote caller did not possess that token, nor did it authenticate with any alternative identity.

Grafana acknowledged the report and explained that the server had shipped without inbound authentication, and noted that the team considered token authentication as a security improvement rather than a vulnerability. The team nevertheless acted quickly: within a few hours of being triaged, v1.1.0 was released, and it added optional bearer-token authentication for SSE and streamable HTTP. When configured, unauthenticated requests receive 401 before any tool runs; the release also logs a security error when an unauthenticated server is bound beyond loopback.

Part two: The server’s network position is also authority

Adding authentication controls who may invoke a tool, but does not determine where that tool may cause the server to connect. Grafana MCP’s grafana_api_request tool accepted X-Grafana-URL, allowing the caller to select the destination of an outbound request. This means the caller could also control the method, path, body, and headers. Grafana had already addressed one important aspect of this design: when X-Grafana-URL selected a different host, the MCP server no longer attached the environment-configured Grafana service-account token. That fix correctly prevented a foreign target from receiving the Grafana credential.

The remaining behavior was still an SSRF primitive. The MCP server connected to the caller-selected destination, transmitted the caller-selected request, and returned the destination’s response.

Our controlled internal canary recorded the requested POST and body. Though it did not receive the Grafana service-account token, confirming the credential-binding protection worked, its response nevertheless reached the MCP caller. The same primitive also supported a controlled IMDSv2-style flow: a caller-selected PUT request and TTL header obtained a metadata session token, then a second caller-controlled request used that token to retrieve canary credentials.

This does not mean that every Grafana MCP deployment could reach cloud metadata. However, it shows the relevant security property: the server can become a readable, method-capable proxy from its own network location. Grafana addressed this SSRF as CVE-2026-19516, scored 9.1 CVSS.

This vulnerability also underscores the true blast radius of the MCP server's authentication posture; not only could access to an MCP server trivially give an attacker a foothold, but access to it could lead to significantly more privileged credentials and lateral movement through the organization.

Watch the controlled demonstration (1:38). The video shows unauthenticated tool execution with the server’s Grafana identity, followed by a method- and header-capable SSRF flow against controlled canaries. No live Grafana instance or cloud metadata service was accessed.

MCP Servers as Identity Brokers

The two findings failed at different points, but exposed the same mismatch: the caller supplied the instruction, while the MCP server supplies the authority.

Without inbound authentication, an unauthenticated caller can cause the server to use its Grafana service-account credential. With the SSRF, an authenticated caller can cause the server to use network reachability the caller does not possess. In both cases, the server acts beyond the caller’s established authority.

What we are realizing is that Session IDs, Host validation, and Origin validation cannot close that gap alone. They manage protocol state or request context; they do not establish caller identity or authorize the downstream action. An MCP server must authenticate the caller, authorize the tool invocation, and constrain the credentials and destinations it may use on that caller’s behalf.

That makes an MCP server more than an API adapter: it can be regarded as an identity broker, translating a caller’s instruction into actions performed with the server’s credentials and network position.

Recommendations for Grafana MCP deployments

Remote MCP deployments need an explicit inbound authentication boundary. Session IDs should be treated as state references, not credentials, and MCP service accounts should have only the Grafana permissions required for the enabled tools.

For tools that issue HTTP requests, the destination policy must be equally explicit. Operators should prefer an allowlist of approved Grafana origins, resolve hostnames before applying destination restrictions, and block loopback, private, link-local, metadata, and other unapproved ranges by default. Revalidating the resolved address at connection time reduces DNS-rebinding exposure. Arbitrary method and header forwarding should also be avoided unless the tool genuinely requires it.

The caller provides the instruction and the server provides the reach. Security depends on keeping those two things connected.

Subscribe and get the latest security updates

Back to blog

MAYBE YOU WILL FIND THIS INTERSTING AS WELL

A WIF Of Fresh Access: How a GitHub Issue on Gemini-CLI Led to GCP Project Compromise

By

Dan Lisichkin

and

August 18, 2026

Research
Lose Control Flow: Unauthenticated Tool Execution in Dolt MCP

By

Ariel Fogel

and

August 13, 2026

Research
Deadbugz: Currently Active MCP Supply-Chain Campaign

By

Ariel Fogel

and

August 12, 2026

Research