dompurify 是纯字符串净化库,不能集成到富文本编辑器ui中运行;必须在提交前、渲染前或服务端入库前调用 sanitize() 处理原始html字符串,并严格配置 forbid_tags、forbid_attr 等选项,且服务端须二次净化。

DOMPurify 不能“集成到 HTML 编辑器”里运行
DOMPurify 不是插件,也不支持在富文本编辑器(如 TinyMCE、Quill、CKEditor)的 UI 层直接“挂载”或“启用”。它是个纯 JavaScript 库,只做一件事:sanitize() 字符串。所有“编辑器内实时拦截 XSS”的幻想,都源于混淆了「输入来源」和「净化时机」——编辑器里用户敲的 HTML 是未信任内容,必须在提交前、渲染前、存库前,用 DOMPurify.sanitize() 处理原始字符串,而不是让它监听编辑器内部 DOM 变化。
真正有效的净化位置只有三个:提交前、渲染前、服务端入库前
你在编辑器里看到的 <img src="x" onerror="alert(1)">,如果直接用 innerHTML = editor.getContent() 插入页面,就已触发 XSS。正确路径是:
- 用户完成编辑后,调用编辑器 API 获取原始 HTML 字符串(如
quill.root.innerHTML、tinymce.activeEditor.getContent()) - 立即传给
DOMPurify.sanitize(),得到净化后字符串 - 再把结果用于渲染(
el.innerHTML = cleanHtml)或提交(fetch(..., { body: JSON.stringify({ html: cleanHtml }) }))
别试图在编辑器 onChange 里反复 sanitize——性能差、光标错乱、样式丢失,且对绕过型 payload(如 <svg><script>...</script></svg> 嵌套)无额外防护力。
DOMPurify.sanitize() 的关键配置项必须显式设置
默认配置不拦截所有 XSS,尤其对 SVG、MathML、注释、data: URL 等高危载体放行。生产环境至少要加:
FORBID_TAGS: ['script', 'object', 'embed', 'iframe', 'frame', 'frameset']FORBID_ATTR: ['onerror', 'onload', 'onclick', 'javascript:', 'data:text/html']USE_PROFILES: { html: true } // 关闭 SVG/MathML 支持RETURN_DOM_FRAGMENT: false // 返回字符串,别返回 DocumentFragment
漏掉 FORBID_ATTR 就可能放过 <div style="background:url(javascript:alert())">;不设 <code>USE_PROFILES 则 SVG 内的 <foreignobject></foreignobject> 仍可执行脚本。
服务端必须二次净化,前端 sanitize 不是银弹
前端用 DOMPurify 处理的是“用户当前提交的内容”,但攻击者可以绕过前端 JS 直接发恶意请求。所以服务端收到 HTML 后,必须用服务端等价净化库(如 Python 的 bleach、Node.js 的 jsdom + DOMPurify 或 sanitize-html)再跑一遍。两个地方缺一不可:
- 前端净化:防误触、提升响应感、减少无效请求
- 服务端净化:防绕过、保数据安全、满足合规底线
DOMPurify 的 isSanitized() 和 addHook() 很少需要,除非你得动态拦截自定义标签;日常使用,盯紧那几个配置项,比研究钩子重要得多。











