fix(CommandPalette): always escape search highlight to prevent XSS (2a172ef)#291
Merged
Conversation
…a172ef) Syncs upstream nuxt/ui commit 2a172ef (#6741) — security fix. The search-highlight helper detected already-escaped HTML entities and skipped re-escaping, letting an attacker bypass escaping by injecting a stray entity — an XSS in CommandPalette result highlighting. - src/runtime/utils/search.ts: remove isAlreadyEscaped()/sanitize() and replace the three sanitize() calls in highlight()'s generateHighlightedText with escapeHTML(). sanitizeSnippet() already used escapeHTML directly (untouched). - test/utils/search.spec.ts: import highlight and add the four upstream XSS regression tests (injected tag in unmatched tail, entity-bypass regression, special chars around a highlight, no-match undefined case). highlight output for normal input is unchanged -> no snapshot churn. Suite: 5565 passed / 6 skipped. Ledger: cursor -> 2a172ef; previous entry f400bc6 reconciled to PR #290. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JS8ypVfQSFzYVZzkTHhURb
IgorShevchik
added a commit
that referenced
this pull request
Jul 20, 2026
Syncs upstream nuxt/ui commit e931bdf. Docs-content refinement of headers-and-text.md (on top of b24ui's post-#287 state): - hash-icon copy "H2 and H3" -> "H2, H3 and H4" - consolidate the two ::note blocks (anchor-links + toc config) into one merged note whose nuxt.config.ts example combines renderer.anchorLinks and build.markdown.toc, linking both generation docs. Docs-content only. Suite: 5565 passed / 6 skipped. Ledger: cursor -> e931bdf; previous entry 2a172ef reconciled to PR #291. Claude-Session: https://claude.ai/code/session_01JS8ypVfQSFzYVZzkTHhURb Co-authored-by: Shevchik Igor <noreply@anthropic.com>
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.
Syncs upstream nuxt/ui commit
2a172ef— fix(CommandPalette): always escape search highlight to prevent XSS (#6741). Security fix.Vulnerability
The search-highlight helper tried to detect already-escaped HTML entities (
isAlreadyEscaped) and skip re-escaping (sanitize). An attacker could inject a stray HTML entity so their payload was treated as "already escaped" and passed through unescaped — an XSS in CommandPalette result highlighting.b24ui port
src/runtime/utils/search.ts— b24ui carried the identical vulnerable code. RemovedisAlreadyEscaped()+sanitize()and replaced all threesanitize()calls inhighlight()'sgenerateHighlightedText(leading unmatched region, matched region, trailing tail) withescapeHTML().sanitizeSnippet()already usedescapeHTMLdirectly — untouched.test/utils/search.spec.ts— importedhighlightand added the four upstream XSS regression tests (injected tag in the unmatched tail; the entity-bypass regression; HTML-special chars around a highlight; the no-matchundefinedcase). b24ui'shighlightmatches upstream 1:1 (minTokenLength = searchTerm.lengthwithout token search; earlyreturnon!item.matches?.length), so the tests port verbatim.Tests
highlightoutput for normal (non-pre-escaped) input is unchanged → no snapshot churn. Suite grows by the 4 new tests (× nuxt+vue): 5565 passed / 6 skipped. (An unrelatedEditorToolbartiming flake surfaced once under full-suite contention and passed on isolated + full reruns.)Verify (
CI=true)dev:prepare·lint·typecheck·test·build— all green.Ledger: cursor advanced to
2a172ef; previous entryf400bc6reconciled to PR #290.🤖 Generated with Claude Code
Generated by Claude Code