Skip to content

fix(security): add DOMPurify sanitization for Markdown rendering XSS - #1212

Open
ErlichLiu wants to merge 1 commit into
mainfrom
fix/markdown-xss-dompurify
Open

fix(security): add DOMPurify sanitization for Markdown rendering XSS#1212
ErlichLiu wants to merge 1 commit into
mainfrom
fix/markdown-xss-dompurify

Conversation

@ErlichLiu

Copy link
Copy Markdown
Collaborator

问题

markdown-rich-text.ts 使用 markdown-ithtml: true)渲染 Markdown,输出通过 innerHTML 赋值给 DOM,缺少 DOMPurify 净化。这是 6 月 23 日深度 Bug 审计中标记的最后一个 P0 安全问题。

修复方案

基于业界调研(Obsidian DOMPurify 方案 + VS Code CSP 纵深防御 + Open WebUI 模式),在 HTML 进入 DOM 前用 DOMPurify 严格配置净化。

改动

  1. 新建 markdown-sanitize.ts — 共享 DOMPurify 净化模块
    • FORBID_TAGS: iframe/object/embed/form 等高危标签(Obsidian 曾因允许 iframe 导致本地文件泄露,HITCON 2023)
    • ALLOW_DATA_ATTR: false: 禁止任意 data-* 属性,防止 DOM clobbering
    • ADD_ATTR 白名单: 只允许 Proma 渲染管线依赖的 data-type/data-html/data-markdown/data-latex 等
  2. 修改 markdown-rich-text.tsenhanceMarkdownHtmlhtmlToMarkdowninnerHTML 前加 sanitizeMarkdownHtml()
  3. 修改 markdown-preview-extensions.tsx — 删除本地 sanitizeHtml 函数,改用共享模块(配置统一,避免漂移)
  4. 新增 7 个 XSS 测试 — script/onerror/javascript:/iframe/object 剥离 + math block/details 保留回归

防御层级

Markdown 输入
  → markdown-it 自定义渲染器(原始 HTML 转义为 data 属性)  ← 第一层
  → DOMPurify.sanitize()(enhanceMarkdownHtml 入口)        ← 第二层(本 PR 新增)
  → TipTap insertContent → NodeView sanitizeMarkdownHtml   ← 第三层(已有,统一配置)

调研依据

产品 策略
ChatGPT/Claude.ai 不允许原始 HTML(react-markdown 默认)
VS Code html:true + Webview CSP 沙箱
Obsidian html:true + DOMPurify(曾因允许 iframe 被攻破)
GitHub 服务端默认剥离原始 HTML
Open WebUI DOMPurify.sanitize(marked.parse(content))

Proma 采用 Obsidian 同路线(DOMPurify),配置比 Obsidian 更严格(禁止 iframe + ALLOW_DATA_ATTR: false)。

- Add shared markdown-sanitize.ts with strict DOMPurify config:
  FORBID_TAGS (iframe/object/embed/form), ALLOW_DATA_ATTR: false,
  explicit ADD_ATTR whitelist for Proma custom data attributes
- Sanitize HTML before innerHTML in enhanceMarkdownHtml and htmlToMarkdown
- Replace local sanitizeHtml in markdown-preview-extensions with shared module
- Add 7 XSS protection tests (script/onerror/javascript:/iframe/object stripping
  + math block/details block preservation)

References: HITCON 2023 Obsidian iframe local file disclosure,
VS Code webview CSP defense-in-depth, Open WebUI DOMPurify pattern
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