Security Alert: Identifying Cross-Site Scripting in Grafana

Essential Details
While inspecting various open-source codes, a Cross-Site Scripting (XSS) focal point was identified in Grafana, a prevalent observability tool, by SonarQube.

[…Keep reading]

Data in Danger: Detecting Cross-Site Scripting in Grafana

Essential Details

While inspecting various open-source codes, a Cross-Site Scripting (XSS) focal point was identified in Grafana, a prevalent observability tool, by SonarQube.
We validated the vulnerability and informed the Grafana developers, who promptly rectified the issue. Additional details can be found in their latest release blog.
This flaw has been designated as CVE-2025-2703 and has been addressed in Grafana version 11.6.0+security-01, with backports available for all existing versions.
If exploited, attackers could use this vulnerability to exfiltrate data from other users or gain elevated privileges by focusing on users with elevated permissions.
Unprotected Grafana installations are left exposed in their default setup, impacting both the open-source (OSS) and Enterprise editions.
The likelihood of widespread exploitation is low as the vulnerability necessitates both authentication and panel editing permissions for the attacker.

Our routine examination of open-source projects aims to enhance software security and enhance our proficiency in security assessments. With the continuous expansion of codebases and the integration of AI-driven programming, there is a growing demand to scrutinize code for security vulnerabilities and other concerns. This underscores the necessity for automated code evaluations to prevent vulnerabilities from seeping into production, as illustrated by our discussion today.

A Cross-Site Scripting (XSS) vulnerability (CVE-2025-2703) was identified in Grafana, a sought-after solution for data visualization and analysis. Following manual verification, we reported the vulnerability to Grafana. This flaw enables an authenticated attacker with editor permissions to run arbitrary JavaScript within a victim’s session when interacting with a dashboard. Considering the specific requirements for exploitation, broad-scale abuse is improbable, leading us to share our insights.

In this article, our primary focus will be on exploring the potential implications of this vulnerability followed by a deeper dive into its technical intricacies for a better understanding. We will also discuss Grafana’s resolution to the issue and provide guidance on preventing similar vulnerabilities in your codebase.

View the detailed report on SonarQube Cloud
Impact
The vulnerability (CVE-2025-2703) had persisted in Grafana, dating back to version 11.1.0 which was released approximately 10 months ago. The remediation was integrated into version 11.6.0+security-01 and backported to all actively supported versions, emphasizing the necessity of updating your instance. For further insights, refer to Grafana’s release blog.

Exploiting this vulnerability empowers an attacker to embed a malicious JavaScript payload into a dashboard panel’s configuration. When a user accesses an affected dashboard, this payload is executed within the victim’s Grafana session, allowing data theft or privilege escalation.

Editor permissions for a dashboard panel are requisite for an attacker to exploit this vulnerability. The vulnerability resides within the native XY Charts plugin, rendering unpatched Grafana installations vulnerable by default. To witness a successful exploitation scenario, refer to the demonstration in a controlled environment below:

Watch the demonstration video
CVE-2025-2703: Technical Overview
Grafana organizes data into dashboards containing multiple panels for visualization from diverse data sources, offering extensive customization capabilities, making it a versatile tool:

To cater to common use cases, Grafana is bundled with various built-in plugins that provide fundamental utilities, including essential chart variations. One such plugin, the XY Chart plugin, is responsible for generating scatter plots from data points:

Diverse customization options, such as altering the color of data points on the grid, are facilitated by this chart. The color can either be static or based on defined thresholds. To prevent performance degradation due to a large volume of data points, Grafana generates a native JavaScript function derived from the defined thresholds, which is executed for each data point during chart rendering.

However, the methodology of creating a JavaScript function from potentially untrusted inputs poses a significant risk. If input segments are integrated unsafely into the function’s code, an attacker can exploit this to inject arbitrary JavaScript code. Let’s examine the issue identified by SonarQube:

The identification flags the precarious generation of a JavaScript function based on a dynamic string as a security focal point. By analyzing the encompassing function (fieldValueColors()), we can discern its construction. While a substantial portion of the function’s code is omitted here for brevity, it’s evident that a portion of the code originates from a configuration object (f.config):
public/app/plugins/panel/xychart/scatter.ts:
function fieldValueColors(f: Field, theme: GrafanaTheme2): FieldColorValues {
// …
let conds = ”;
if (f.config.mappings?.length ?? 0 > 0) {
// …
} else if (f.config.color?.mode === FieldColorModeId.Thresholds) {
if (f.config.thresholds?.mode === ThresholdsMode.Absolute) {
let steps = f.config.thresholds.steps;
let lasti = steps.length – 1;
for (let i = lasti; i > 0; i–) {
conds += `v >= ${steps[i].value} ? ${i} : `;
}
// …
} else {
// …
}
}
// …
if (conds !== ”) {
getOne = new Function(‘v’, `return ${conds};`) as GetOneValue;
// …
}
// …
}

This configuration object contains alterable values accessible during panel editing. The values within the thresholds.steps array are directly injected into the function’s code without being escaped or sanitized in line 11. This observation points towards an existing vulnerability! However, this hinges on the assumption that the values remain unaltered by the server supplying the configuration.

In addition to an editor interface, Grafana supports panel modification by directly editing its JSON representation:

The structural resemblance to what the fieldValueColors() function anticipates is apparent here. Given that the current values are all numeric, aligning with the function’s expectations due to the employment of greater-than comparison operators with these values. However, as the panel is stored in JSON format, an attacker could simply substitute the numerical values with strings containing JavaScript code. Experiments confirm the viability of this manipulation, indicating a lack of validation or sanitation by the server:

This experiment validates the authenticity of the security concern highlighted by SonarQube. We promptly notified the Grafana team about this finding, and the subsequent section discusses their resolution to this issue.

Resolution
To preclude the emergence of similar vulnerabilities, it is vital to diligently escape or sanitize untrusted inputs before implementation in JavaScript code segments. Grafana addressed this vulnerability by converting the threshold value to a numeric format:
– conds += `v >= ${steps[i].value} ? ${i} : `;
+ let rhs = Number(steps[i].value);
+ conds += `v >= ${rhs} ? ${i} : `;

Timeline

Date
Action

2025-03-14
Submission of our advisory to the Grafana team via PGP-encrypted email

2025-03-21
Confirmation of receipt of our report by the Grafana team

2025-04-15
Progress update from the Grafana team with the assignment of CVE-2025-2703

2025-04-22
Publishing of the fix by the Grafana team in version 11.6.0+security-01, with backports to all active versions

2025-04-23
Publication of the vulnerability details by the Grafana team in their release blog post

2025-04-24
Publishing of this blog post by our team

Synopsis
Through this blog post, we have examined a significant Cross-Site Scripting vulnerability within Grafana’s code, a popular data analytics tool. We’ve demonstrated how our open-source scanning methodology operates, from the initial identification through validation and reporting to the software provider.

The prevalence of vulnerabilities in well-established codebases emphasizes the criticality of continuous code audits as more code is generated by both traditional methods and AI-driven approaches.

Furthermore, an intriguing correlation between Cognitive Complexity and vulnerability inclination is observed. SonarQube’s identification of the vulnerable function is not solely attributed to its susceptibility but also to its complexity, featuring numerous nested loops and conditional statements. This complexity poses challenges for comprehension, increasing the likelihood of oversight concerning user inputs integrated into hazardous functions.

Lastly, we extend our gratitude to the Grafana team for their prompt remediation and transparent communication during the disclosure.
Related Blog Posts

*** This is a Security Bloggers Network syndicated blog from Blog RSS feed authored by Paul Gerste. Read the original post at: https://www.sonarsource.com/blog/data-in-danger-detecting-xss-in-grafana-cve-2025-2703/

About Author

Subscribe To InfoSec Today News

You have successfully subscribed to the newsletter

There was an error while trying to send your request. Please try again.

World Wide Crypto will use the information you provide on this form to be in touch with you and to provide updates and marketing.