Skip to content

fix(editor): prevent XSS in details summary previews - #2942

Merged
bobleer merged 1 commit into
GCWing:mainfrom
bobleer:bob/fix-markdown-summary-xss
Sep 10, 2026
Merged

fix(editor): prevent XSS in details summary previews#2942
bobleer merged 1 commit into
GCWing:mainfrom
bobleer:bob/fix-markdown-summary-xss

Conversation

@bobleer

@bobleer bobleer commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fix XSS in the Markdown editor’s source-backed details summary preview. Sanitize descendants before unwrapping unsupported HTML elements, reject foreign namespaces, and validate link/image protocols using browser URL parsing and explicit allowlists. Without a DOM, return escaped text instead of raw HTML.

Type and Areas

Type: Bug fix (security)

Areas: Web UI / Markdown editor, browser regression tests

Motivation / Impact

The previous traversal could retain event handlers inside an unsupported wrapper. Its URL prefix check also missed control characters normalized by the browser. These paths could execute document-controlled JavaScript when rendering or interacting with a details summary, including live source-block edits.

The fix preserves supported formatting, links, image metadata, and original Markdown bytes. Regression coverage exercises both initial document loading and live editing; the initial parser and source-backed preview use different paths.

Verification

  • Focused editor/Markdown unit and DOM suite: 151 passed, including 39 new sanitizer cases:
pnpm --dir src/web-ui run test:run src/tools/editor/meditor/utils/sanitizeDetailsSummaryHtml.test.ts src/tools/editor/components/MarkdownEditor.test.tsx src/tools/editor/meditor/components/MEditor.test.tsx src/tools/editor/meditor/utils/tiptapMarkdown.test.ts src/tools/editor/meditor/utils/embeddedSource.test.ts src/tools/editor/meditor/utils/markdownFrontmatter.test.ts src/tools/editor/meditor/components/Preview.test.tsx src/tools/editor/meditor/utils/loadLocalImages.test.ts src/infrastructure/markdown/rehypeSourceRange.test.ts src/infrastructure/markdown/MarkdownRenderer.test.tsx
  • pnpm run check:web: passed.
  • pnpm --dir src/web-ui exec tsc --noEmit: passed on the final implementation.
  • pnpm --dir src/web-ui exec vitest run src/tools/editor/meditor/utils/sanitizeDetailsSummaryHtml.test.ts: 39 passed after the final traversal adjustment.
  • pnpm --dir tests/e2e exec wdio run ./config/wdio.markdown-browser.ts: the 10 existing browser cases passed. After correcting the new test fixture and interaction steps, pnpm --dir tests/e2e exec wdio run ./config/wdio.markdown-browser.ts --mochaOpts.grep 'sanitizes loaded' passed the new security case, including no script execution and exact save/source round-trip preservation.
  • Browser verification used Node 24 and Chrome 152; local Node 26 failed to create a WebDriver session. The incomplete local driver cache was repaired before the successful runs.
  • Focused sanitizer ESLint and git diff --check: passed.

Reviewer Notes

AI-assisted implementation; testing level: focused automated unit/DOM and real-browser verification. No native Tauri, live SSH workspace, Remote Connect, Peer Device Mode, or Detached Dispatch execution was tested. Relative and supported host/workspace URLs are covered as sanitizer inputs; that is not live remote-transport coverage.

No server configuration, dependency versions, persisted schemas, or user-facing strings change. No migration is required.

Checklist

  • This PR is focused and does not include secrets, temporary prompts, generated scratch files, or unrelated artifacts.
  • Relevant verification is recorded above, or skipped checks are explained.
  • User-facing strings, docs, and locales are updated where applicable (no changes required).

@bobleer
bobleer merged commit 637762f into GCWing:main Sep 10, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant