{"schema":"threatline.record/2","record":{"id":"CVE-2026-118247","aliases":["GHSA-c75x-9x9h-28rm"],"summary":"Highcharts Dashboards / Grid Pro: `DataTable.setCell` and column writers treat `__proto__` as an existing column.","details":"### Impact\nWhen a single cell value is written to a data table, the column id is used as a key on the table's column collection without filtering, so a column id of `__proto__` resolves to `Object.prototype`, is taken for an existing column, and the write lands at the row index on `Object.prototype`; a column id of `constructor` writes onto the `Object` constructor in the same way. In Dashboards releases that still supported column aliases, the id is first resolved through the alias map, so a literal `__proto__` id is redirected harmlessly there, while an alias whose target is `__proto__`, which the connector's data table options accept, reaches the same write. An attacker who controls the column id can thereby set integer-keyed properties on `Object.prototype`, one per row index, holding the written value; named properties cannot be reached through these paths, because the row index is a number. The integer keys still affect every object in the page: reading an out-of-range index on any array or plain object returns the injected value, and `for...in` over any object yields the injected keys, so unrelated code can take branches it should not using attacker-supplied data, and rendering can fail as a side effect. In Dashboards the write is reached through the Highcharts component's connector write-back, which is enabled by default through `allowConnectorUpdate` and takes the column id from the component's `columnAssignment`, or in the earliest releases from the series name, when a point is updated; in Grid Pro it is reached through cell editing in earlier releases and remains reachable through the public `DataTable` API. Exploitation requires that untrusted data reach the board or Grid configuration and that a point be updated or a cell edited, or that the application write a cell with an untrusted column id.\n\nConsequences beyond disruption depend on the consuming application.\n\n### Workarounds\nTwo measures are needed. The first closes the paths that reach `Object.prototype`; the second covers table construction, which cannot be patched from outside the library.\n\n#### 1. Strip unsafe keys from untrusted column data\n\nApply this wherever column data enters your application, before it is handed to a grid, board or `DataTable`. This is the only measure that covers the `DataTable` constructor.\n\n```js\nfunction stripUnsafeColumnIds(columns) {\n    for (const key of ['__proto__', 'constructor']) {\n        if (Object.prototype.hasOwnProperty.call(columns, key)) {\n            delete columns[key];\n        }\n    }\n\n    return columns;\n}\n\nGrid.grid('container', {\n    data: { columns: stripUnsafeColumnIds(untrustedColumns) }\n});\n```\n\n#### 2. Patch the DataTable methods\n\nNeeded if your application passes column ids that originate from untrusted input to `setCell`, `changeColumnId` or `setColumns`. Run it once at startup.\n\n```js\n{\n    const { DataTable } = Grid; // Or Dashboards\n\n    if (!DataTable) {\n        throw new Error('Patch loaded before Grid');\n    }\n\n    const unsafe = (id) => id === '__proto__' || id === 'constructor';\n\n    const setCell = DataTable.prototype.setCell;\n    DataTable.prototype.setCell = function (columnId, ...rest) {\n        if (unsafe(columnId)) {\n            return;\n        }\n        return setCell.call(this, columnId, ...rest);\n    };\n\n    const changeColumnId = DataTable.prototype.changeColumnId;\n    DataTable.prototype.changeColumnId = function (columnId, newColumnId) {\n        if (unsafe(columnId) || unsafe(newColumnId)) {\n            return false;\n        }\n        return changeColumnId.call(this, columnId, newColumnId);\n    };\n\n    const setColumns = DataTable.prototype.setColumns;\n    DataTable.prototype.setColumns = function (columns, ...rest) {\n        const safe = {};\n\n        for (const key of Object.keys(columns || {})) {\n            if (!unsafe(key)) {\n                safe[key] = columns[key];\n            }\n        }\n\n        return setColumns.call(this, safe, ...rest);\n    };\n}\n```\n\nFor npm, take `DataTable` from your import instead of the global — it is exported by Grid Lite, Grid Pro and Dashboards alike.\n\n### Obtaining the patched version\nThe patched releases are available from all the usual distribution channels. With npm, upgrade the affected package to the patched version listed above, for example `npm install @highcharts/dashboards@4.2.2`. If you load Highcharts Dashboards from a CDN, use a versioned URL, for example `https://code.highcharts.com/dashboards/4.2.2/dashboards.js`. For more on each installation method, see the [installation guide](https://www.highcharts.com/docs/dashboards/installation).","categories":["Libraries & packages"],"product":"@highcharts/dashboards","vendor":"highcharts","ecosystem":"npm","affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-c75x-9x9h-28rm","source_modified_at":"2026-10-28T19:55:37Z","fetched_at":"2026-10-28T20:58:01.013507Z","package":{"ecosystem":"npm","name":"@highcharts/dashboards"},"range":">= 1.0.0, <= 4.2.1"},{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-c75x-9x9h-28rm","source_modified_at":"2026-10-28T19:55:37Z","fetched_at":"2026-10-28T20:58:01.013507Z","package":{"ecosystem":"npm","name":"@highcharts/grid-pro"},"range":">= 2.0.0, <= 3.1.0"},{"source":"CVE List","source_url":"https://www.cve.org/CVERecord?id=CVE-2026-118247","source_modified_at":"2026-10-28T17:50:59.526Z","fetched_at":"2026-10-28T20:58:01.013507Z","product":"highcharts","vendor":"highcharts","versions":[{"version":"< 13.1.0","status":"affected"}],"defaultStatus":null},{"source":"CVE List","source_url":"https://www.cve.org/CVERecord?id=CVE-2026-118247","source_modified_at":"2026-10-28T17:50:59.526Z","fetched_at":"2026-10-28T20:58:01.013507Z","product":"dashboards","vendor":"@highcharts","versions":[{"version":">= 1.0.0, < 4.2.3","status":"affected"}],"defaultStatus":null},{"source":"CVE List","source_url":"https://www.cve.org/CVERecord?id=CVE-2026-118247","source_modified_at":"2026-10-28T17:50:59.526Z","fetched_at":"2026-10-28T20:58:01.013507Z","product":"grid-pro","vendor":"@highcharts","versions":[{"version":">= 2.0.0, < 3.2.0","status":"affected"}],"defaultStatus":null},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-c75x-9x9h-28rm","source_modified_at":"2026-10-28T20:15:05.454379690Z","fetched_at":"2026-10-28T20:58:01.013507Z","package":{"name":"@highcharts/dashboards","ecosystem":"npm","purl":"pkg:npm/%40highcharts/dashboards"},"ranges":[{"type":"SEMVER","events":[{"introduced":"1.0.0"},{"fixed":"4.2.2"}]}],"versions":[]},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-c75x-9x9h-28rm","source_modified_at":"2026-10-28T20:15:05.454379690Z","fetched_at":"2026-10-28T20:58:01.013507Z","package":{"name":"@highcharts/grid-pro","ecosystem":"npm","purl":"pkg:npm/%40highcharts/grid-pro"},"ranges":[{"type":"SEMVER","events":[{"introduced":"2.0.0"},{"fixed":"3.2.0"}]}],"versions":[]}],"fixed_versions":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-c75x-9x9h-28rm","source_modified_at":"2026-10-28T19:55:37Z","fetched_at":"2026-10-28T20:58:01.013507Z","package":{"ecosystem":"npm","name":"@highcharts/dashboards"},"version":"4.2.2"},{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-c75x-9x9h-28rm","source_modified_at":"2026-10-28T19:55:37Z","fetched_at":"2026-10-28T20:58:01.013507Z","package":{"ecosystem":"npm","name":"@highcharts/grid-pro"},"version":"3.2.0"},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-c75x-9x9h-28rm","source_modified_at":"2026-10-28T20:15:05.454379690Z","fetched_at":"2026-10-28T20:58:01.013507Z","package":{"name":"@highcharts/dashboards","ecosystem":"npm","purl":"pkg:npm/%40highcharts/dashboards"},"version":"4.2.2"},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-c75x-9x9h-28rm","source_modified_at":"2026-10-28T20:15:05.454379690Z","fetched_at":"2026-10-28T20:58:01.013507Z","package":{"name":"@highcharts/grid-pro","ecosystem":"npm","purl":"pkg:npm/%40highcharts/grid-pro"},"version":"3.2.0"}],"cvss":6.9,"severity":"Medium","kev":{"listed":false},"epss":{"probability":null,"percentile":null,"score_date":null},"published_at":"2026-10-28T17:50:59.526Z","modified_at":"2026-10-28T20:15:05.454379690Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/advisories/GHSA-c75x-9x9h-28rm","fetched_at":"2026-10-28T20:58:01.013507Z","source_modified_at":"2026-10-28T19:55:37Z"},{"source":"CVE List","url":"https://www.cve.org/CVERecord?id=CVE-2026-118247","fetched_at":"2026-10-28T20:58:01.013507Z","source_modified_at":"2026-10-28T17:50:59.526Z"},{"source":"OSV","url":"https://osv.dev/vulnerability/GHSA-c75x-9x9h-28rm","fetched_at":"2026-10-28T20:58:01.013507Z","source_modified_at":"2026-10-28T20:15:05.454379690Z"}],"sources":["GitHub Advisory Database","CVE List","OSV"],"references":[{"source":"CVE List","url":"https://github.com/highcharts/highcharts/security/advisories/GHSA-c75x-9x9h-28rm","tags":["x_refsource_CONFIRM"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-118247","source":"GitHub Advisory Database"},{"source":"CVE List","url":"https://github.com/highcharts/highcharts/commit/02dd9349aeb6f4cc9c98806120d917ed316b4c74","tags":["x_refsource_MISC"]},{"source":"CVE List","url":"https://github.com/highcharts/highcharts/releases/tag/dashboards-v4.2.2","tags":["x_refsource_MISC"]},{"source":"CVE List","url":"https://github.com/highcharts/highcharts/releases/tag/grid-v3.2.0","tags":["x_refsource_MISC"]},{"url":"https://github.com/advisories/GHSA-c75x-9x9h-28rm","source":"GitHub Advisory Database"}],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"cve_state":"PUBLISHED","classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":"ecosystem","confidence":"heuristic","reviewed":false},"change_timestamp":"2026-10-28T20:15:05.454379690Z","content_hash":"458c093a0c3f494043d437fd5b0d83dbe352a6e517de0f20a453b960334d61bc"}}
