CVE-2026-0824
Description
A security flaw has been discovered in questdb ui up to 1.11.9. Impacted is an unknown function of the component Web Console. The manipulation results in cross site scripting. The attack can be executed remotely. The exploit has been released to the public and may be used for attacks. Upgrading to version 1.1.10 is recommended to address this issue. The patch is identified as b42fd9f18476d844ae181a10a249e003dafb823d. You should upgrade the affected component. The vendor confirmed early that the fix "is going to be released as a part of QuestDB 9.3.0" as well.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
@questdb/web-consolenpm | < 1.1.10 | 1.1.10 |
Affected products
1Patches
1b42fd9f18476fix XSS security vulnerability (#519)
4 files changed · +41 −38
e2e/tests/console/aiAssistant.spec.js+9 −5 modified@@ -1274,17 +1274,21 @@ describe("ai assistant", () => { }) describe("explain schema", () => { - beforeEach(() => { - cy.loadConsoleWithAuth(false, getOpenAIConfiguredSettings()) + before(() => { + cy.loadConsoleWithAuth() cy.typeQuery( "CREATE TABLE IF NOT EXISTS test_trades (symbol SYMBOL, price DOUBLE, ts TIMESTAMP) TIMESTAMP(ts) PARTITION BY DAY WAL;", ) cy.clickRunQuery() + cy.refreshSchema() + }) + after(() => { + cy.loadConsoleWithAuth() + cy.dropTable("test_trades") }) - afterEach(() => { - cy.typeQuery("DROP TABLE IF EXISTS test_trades;") - cy.clickRunQuery() + beforeEach(() => { + cy.loadConsoleWithAuth(false, getOpenAIConfiguredSettings()) }) it("should show processing status and display valid schema explanation", () => {
src/js/console/grid.js+18 −31 modified@@ -33,17 +33,6 @@ const hashString = (str) => { return new Uint32Array([hash])[0].toString(36) } -const escapeHtml = (text) => { - const map = { - "<": "<", - ">": ">", - '"': """, - "'": "'", - } - - return text.replace(/[<>"']/g, (m) => map[m]) -} - export function grid(rootElement, _paginationFn, id) { const defaults = { gridID: "qdb-grid", @@ -963,26 +952,26 @@ export function grid(rootElement, _paginationFn, id) { const hType = document.createElement("span") addClass(hType, "qg-header-type") if (c.type !== "ARRAY") { - hType.innerHTML = c.type.toLowerCase() + hType.textContent = c.type.toLowerCase() } else if (c.dim > 2) { - hType.innerHTML = + hType.textContent = c.type.toUpperCase() + "(" + c.elemType.toUpperCase() + "," + c.dim + ")" } else { - let html = c.elemType.toLowerCase() + "[]" + let typeText = c.elemType.toLowerCase() + "[]" if (c.dim > 1) { - html += "[]" + typeText += "[]" } - hType.innerHTML = html + hType.textContent = typeText } const hName = document.createElement("span") addClass(hName, "qg-header-name") - hName.innerHTML = c.name + hName.textContent = c.name const hysteresis = document.createElement("div") addClass(hysteresis, "qg-col-resize-hysteresis") @@ -1106,14 +1095,12 @@ export function grid(rootElement, _paginationFn, id) { } function getArrayString(cellData) { - return escapeHtml( - JSON.stringify(cellData, (_, val) => { - if (Number.isInteger(val)) { - return val.toString() + ".0" - } - return val - }).replace(/"/g, ""), - ) + return JSON.stringify(cellData, (_, val) => { + if (Number.isInteger(val)) { + return val.toString() + ".0" + } + return val + }).replace(/"/g, "") } function getDisplayedCellValue(column, cellData, columnWidth = null) { @@ -1126,10 +1113,10 @@ export function grid(rootElement, _paginationFn, id) { if (!isArray) { if (containsPrecision) { return Number.isInteger(cellData) - ? escapeHtml(cellData.toString() + ".0") - : escapeHtml(cellData.toString()) + ? cellData.toString() + ".0" + : cellData.toString() } - return escapeHtml(cellData.toString()) + return cellData.toString() } const arrayString = getArrayString(cellData) @@ -1166,15 +1153,15 @@ export function grid(rootElement, _paginationFn, id) { if (cellData !== null) { const layoutEntry = getLayoutEntry() const columnWidth = layoutEntry.deviants[column.name] ?? null - cell.innerHTML = getDisplayedCellValue(column, cellData, columnWidth) + cell.textContent = getDisplayedCellValue(column, cellData, columnWidth) cell.classList.remove("qg-null") if (column.type === "ARRAY") { cell.classList.add("qg-arr") } } else { - cell.innerHTML = "null" + cell.textContent = "null" cell.classList.add("qg-null") } } @@ -1769,7 +1756,7 @@ export function grid(rootElement, _paginationFn, id) { } addClass(focusedCell, "qg-c-active-pulse") - let valueToCopy = focusedCell.innerHTML + let valueToCopy = focusedCell.textContent if (focusedCell.classList.contains("qg-arr")) { const rowIndex = focusedCell.parentElement.rowIndex
src/js/console/quick-vis.ts+3 −2 modified@@ -38,6 +38,7 @@ import eChartsMacarons from "./utils/macarons" import { arrayEquals } from "./array-equals" import { eventBus } from "../../modules/EventBus" import { EventType } from "../../modules/EventBus/types" +import { escapeHtml } from "../../utils/escapeHtml" import * as QuestDB from "../../utils/questdb" import { AnyIfEmpty } from "react-redux" import { request } from "http" @@ -290,12 +291,12 @@ export function quickVis( const x = [] const columns = data.columns for (let i = 0; i < columns.length; i++) { - x[i] = { text: columns[i].name, value: columns[i].name } + x[i] = { text: escapeHtml(columns[i].name), value: columns[i].name } } xAxisPicker.setData(x) yAxisPicker.setData(x) - yAxisPicker.set(x.slice(1).map((item) => item.text)) + yAxisPicker.set(x.slice(1).map((item) => item.value)) // stash query text so that we can use this later to server for chart column values query = data.query
src/utils/escapeHtml.ts+11 −0 added@@ -0,0 +1,11 @@ +export const escapeHtml = (text: string): string => { + const map: Record<string, string> = { + "&": "&", + "<": "<", + ">": ">", + '"': """, + "'": "'", + } + + return text.replace(/[&<>"']/g, (m) => map[m]) +}
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
10- github.com/advisories/GHSA-xf94-h87h-g9wrghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-0824ghsaADVISORY
- github.com/59lab/dbdb/blob/main/There%20is%20a%20cross-site%20scripting(XSS)%20vulnerability%20in%20the%20QuestDB%20database.mdnvdWEB
- github.com/questdb/questdb/releases/tag/9.3.0nvdWEB
- github.com/questdb/ui/commit/b42fd9f18476d844ae181a10a249e003dafb823dnvdWEB
- github.com/questdb/ui/pull/518nvdWEB
- github.com/questdb/ui/pull/519nvdWEB
- vuldb.comnvdWEB
- vuldb.comnvdWEB
- vuldb.comnvdWEB
News mentions
0No linked articles in our index yet.