Apache ECharts: XSS in Lines series tooltip rendering
Description
A cross-site scripting (XSS) vulnerability exists in Apache ECharts in the Lines series tooltip rendering logic.
This issue affects Apache ECharts: from before 6.1.0.
In versions prior to 6.1.0, if both Lines series and tooltip are used, and no user-specified tooltip.formatter is provided, and series.data[i].name is specified, raw HTML string series.data[i].name can be rendered through innerHTML sink into tooltip content. Although tooltip is allowed to accept user-provided raw HTML via a custom tooltip.formatter, the built-in tooltip formatters conventionally perform HTML escaping automatically. This case breaks that convention and may unexpectedly lead to script execution when tooltips are displayed.
Users are recommended to upgrade to version 6.1.0 if using the Lines series in this way, which fixes the issue.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
XSS vulnerability in Apache ECharts Lines series tooltip allows script execution via unescaped data.name, fixed in 6.1.0.
Vulnerability
A cross-site scripting (XSS) vulnerability exists in Apache ECharts in the Lines series tooltip rendering logic. In versions prior to 6.1.0, if both lines series and tooltip are used, and no user-specified tooltip.formatter is provided, and series.data[i].name is specified, the raw HTML string from series.data[i].name can be rendered through an innerHTML sink into tooltip content [1][2]. This breaks the convention that built-in tooltip formatters automatically escape HTML, potentially leading to script execution when tooltips are displayed [2].
Exploitation
An attacker must be able to control or influence the name property of data items in a Lines series (e.g., by providing untrusted data to the chart). When a user hovers over or interacts with the Lines series to trigger the tooltip, the injected HTML/JavaScript is executed in the context of the user's browser session [1][2]. No authentication or special network position is required beyond supplying the malicious data to the ECharts instance [1].
Impact
Successful exploitation allows an attacker to execute arbitrary JavaScript in the victim's browser (XSS). This can lead to session hijacking, data theft, defacement, or other malicious actions within the context of the application using ECharts [1][2]. The privilege level is that of the victim user.
Mitigation
Upgrade to Apache ECharts version 6.1.0 or later, which fixes the vulnerability by routing line tooltip content through a markup builder that HTML-encodes the name [2]. Users who cannot upgrade and are using the Lines series with tooltip should either provide a custom tooltip.formatter that safely escapes user input, or ensure that all series.data[i].name values are sanitized before being passed to the chart [1].
AI Insight generated on May 25, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1Patches
11e39b00eeddaMerge pull request #21608 from apache/fix/lines-tooltip-xss
2 files changed · +115 −9
src/chart/lines/LinesSeries.ts+12 −9 modified@@ -337,19 +337,22 @@ class LinesSeriesModel extends SeriesModel<LinesSeriesOption> { dataType: string ) { const data = this.getData(); + const value = this.getRawValue(dataIndex); const itemModel = data.getItemModel<LinesDataItemOption>(dataIndex); - const name = itemModel.get('name'); - if (name) { - return name; + let itemName = itemModel.get('name'); + if (!itemName) { + const fromName = itemModel.get('fromName'); + const toName = itemModel.get('toName'); + const nameArr = []; + fromName != null && nameArr.push(fromName); + toName != null && nameArr.push(toName); + itemName = nameArr.join(' > '); } - const fromName = itemModel.get('fromName'); - const toName = itemModel.get('toName'); - const nameArr = []; - fromName != null && nameArr.push(fromName); - toName != null && nameArr.push(toName); return createTooltipMarkup('nameValue', { - name: nameArr.join(' > ') + name: itemName, + value, + noValue: value == null || isNaN(value as number) }); }
test/tooltip-xss.html+103 −0 added@@ -0,0 +1,103 @@ +<!DOCTYPE html> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> + + +<html> + <head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <script src="lib/simpleRequire.js"></script> + <script src="lib/config.js"></script> + <script src="lib/facePrint.js"></script> + <script src="lib/testHelper.js"></script> + <!-- <script src="lib/canteen.js"></script> --> + <!-- <script src="lib/draggable.js"></script> --> + <link rel="stylesheet" href="lib/reset.css" /> + </head> + <body> + <style> + html { + /* Fix the line-height to integer to avoid it varying across clients and + causing visual test failures. Some clients may not support fractional px. */ + line-height: 18px; + } + </style> + + <div id="main0"></div> + + <script> + require([ + 'echarts', + 'map/js/world' + ], function (echarts) { + var option = { + tooltip: { trigger: 'item' }, + geo: { map: 'world' }, + series: { + type: 'lines', + coordinateSystem: 'geo', + data: [ + { + name: '<img src="x" onerror="onXSSTriggered(1)"/>', + coords: [ + [110, -80], + [111, 80] + ], + value: 800 + }, + { + name: '<img src="x" onerror="onXSSTriggered(2)"/>', + coords: [ + [100, -80], + [101, 80] + ], + value: NaN + } + ], + // tooltip: { + // valueFormatter: v => v + ' unit' + // } + } + }; + window.onXSSTriggered = function () { + console.error('XSS triggered!'); + chart.getDom().innerHTML = '<center style="margin-top:20px;color:red">XSS triggered</center>'; + }; + + var chart = testHelper.create(echarts, 'main0', { + title: [ + 'Hover the vertical line to see tooltip', + '(SHOULD **NOT** see the red "XSS triggered" text)' + ], + option: option + }); + chart.dispatchAction({ + type: 'showTip', + seriesIndex: 0, + dataIndex: 0, + position: ['50%', '50%'] + }); + }); + </script> + + + </body> +</html> +
Vulnerability mechanics
Root cause
"Missing HTML escaping in the Lines series tooltip formatter allows raw `data[i].name` strings to be injected into the DOM via innerHTML."
Attack vector
An attacker who can control the `name` field of a data point in a Lines series (e.g., via user-supplied data) can inject arbitrary HTML, including `
Affected code
The vulnerability is in `src/chart/lines/LinesSeries.ts`, specifically in the `formatTooltip` method of `LinesSeriesModel`. The method previously returned the raw `name` string from `series.data[i].name` directly, which could contain unescaped HTML. The patch routes the output through `createTooltipMarkup('nameValue', ...)` to ensure HTML encoding.
What the fix does
The patch modifies `formatTooltip` in `LinesSeriesModel` to pass the item name through `createTooltipMarkup('nameValue', ...)` instead of returning it as a raw string. This builder function HTML-encodes the name content, preventing script injection. The patch also adds a `noValue` flag to suppress display when the value is missing or NaN, and includes a manual test page (`test/tooltip-xss.html`) that verifies injected `
Preconditions
- configThe application uses Apache ECharts version prior to 6.1.0
- configA Lines series is configured with tooltip enabled and no custom tooltip.formatter
- inputThe attacker can control the name field of a data point in the Lines series data array
- inputThe user hovers over or triggers a tooltip on the affected data point
Reproduction
Create an ECharts chart with a Lines series and tooltip enabled. Set `series.data[i].name` to a malicious HTML string such as `
Generated on May 25, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/apache/echarts/pull/21608mitrepatchtechnical-description
- lists.apache.org/thread/1g6xk7gd9vg1c6zyqqt2lnko10zomc3omitrevendor-advisory
- echarts.apache.org/handbook/en/best-practices/security/mitretechnical-description
- echarts.apache.org/en/option.htmlmitre
News mentions
0No linked articles in our index yet.