Conversation
CommandPalette.svelte renders each entry with {@html command.text}
(:243). command.text comes from fuzzy.filter(..., { pre: '<b>', post:
'</b>' }), which inserts that markup into the raw, unescaped source
string, and the source strings include database, table, view,
collection, procedure and function names loaded verbatim from
database-connections/structure (metadataLoaders.ts). An object name
containing markup reached {@html} unescaped.
Passes the fuzzy match result through DOMPurify.sanitize before it is
stored as command.text, allowing only the <b> highlight tag the
matcher itself produces and no attributes, the same DOMPurify call
this package already uses for {@html} in FontIcon.svelte.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
CommandPalette.svelterenders each palette entry with{@html command.text}(:243).command.textcomes fromfuzzy.filter(filter, ..., { extract: x => _tval(x.text), pre: '<b>', post: '</b>' }), run over the current commands or, when the palette shows database objects, over table/view/collection/procedure/function/database names loaded viadatabase-connections/structure(metadataLoaders.ts).fuzzyinserts thepre/postmarkup into the matched source string without escaping it, so a name containing HTML reaches{@html}unchanged.Why
packages/webalready has the same problem solved for a different{@html}call:FontIcon.sveltepasses an SVG icon string throughDOMPurify.sanitize(iconValue, { USE_PROFILES: { svg: true, svgFilters: true } })before its own{@html sanitizedSvg}.CommandPalettehad no equivalent step between thefuzzymatch and the render.How
The
.map()that builds the palette's rendered rows now sanitizesx.stringwithDOMPurify.sanitize(x.string, { ALLOWED_TAGS: ['b'], ALLOWED_ATTR: [] })before assigning it totext, keeping only the<b>tagfuzzyitself inserts for the highlight and dropping every other tag and attribute.dompurifyis already a dependency ofdbgate-web(^3.3.2), no new dependency is added.Left unchanged:
fuzzy's matching and scoring logic and itspre/postmarkers. The plain command-list path (non-database-object commands) goes through the same.map()and so now gets sanitized too, even though itstextvalues are static UI strings. Two other{@html}call sites in this package are also left alone:elements/DiffView.svelte:17renders output produced bydiff2html, andcelldata/HtmlCellView.svelte:7-12renders a grid cell verbatim as part of an explicit view-as-HTML mode the user selects. Both differ from the palette, where the value is rendered without the user asking for HTML, so they are out of scope here.Testing
packages/webhas no unit test runner configured (package.jsononly definesvalidate=svelte-check, no jest/vitest); no test was added, none was inventeddompurify@3.4.13, matching the pinned dependency, againstjsdomin a scratch directory):x<b>foo</b><img src=x onerror=alert(document.cookie)>sanitizes tox<b>foo</b>;<script>alert(1)</script>sanitizes to an empty string;<b onmouseover=alert(1)>evil</b>sanitizes to<b>evil</b>; a plain highlightmy<b>Table</b>Namepasses through unchangedsvelte-check --workspace packages/webwas run; it reports pre-existing errors across most files in this checkout (Cannot find module 'svelte/compiler',Cannot find module 'dbgate-datalib') unrelated to this change, plus a pre-existing hint onCommandPalette.svelte's untouched line 75 (unusedfilterNameimport); no new error appears on the changed linesReferences
GHSA-qv2r-5c8w-98qq (found during penetration test by turingpoint, reported privately, unpublished at time of writing)