DOMPurify是JavaScript库,需调用sanitize()净化HTML字符串后再渲染;正则过滤不可靠,它基于真实DOM白名单解析;生产环境须显式配置ALLOWED_TAGS/ATTR并限制URI协议,且前后端均需净化。

DOMPurify 不是 HTML 中“直接用”的东西——它是一个 JavaScript 库,必须在 JS 环境里调用 DOMPurify.sanitize() 才能起作用。把用户输入的 HTML 字符串丢给它,它返回净化后的字符串,你再用 v-html、innerHTML 或服务端模板安全渲染。
为什么不能只靠前端 filter(比如正则或 innerHTML + 转义)
正则匹配 HTML 是公认的反模式:嵌套标签、注释、CDATA、属性引号省略、大小写混用、Unicode 变体都能绕过。例如:<img/src="x" onerror=alert(1)> 里空格被全角替代、onerror 首字母大写、或包裹在 <!-- --> 里,多数正则就失效了。DOMPurify 基于真实 DOM 解析,还原结构后再按白名单裁剪,这才是可靠路径。
DOMPurify.sanitize() 的最小可行配置
不传配置时,DOMPurify.sanitize() 默认启用严格白名单(允许 a、br、p、strong 等约 30 个基础标签),但会保留 style 和 class 属性——这可能带来 CSS 注入风险(如 style="background:url(javascript:...)")。生产环境务必显式控制:
import DOMPurify from 'dompurify';
<p>const config = {
ALLOWED_TAGS: ['p', 'br', 'strong', 'em', 'a', 'ul', 'ol', 'li'],
ALLOWED_ATTR: ['href', 'title', 'target'],
FORBID_TAGS: ['script', 'style', 'iframe', 'object', 'embed'],
FORBID_ATTR: ['onerror', 'onload', 'onclick', 'javascript:', 'data:text/html']
};</p><p>const clean = DOMPurify.sanitize(dirtyHtml, config);立即学习“前端免费学习笔记(深入)”;
注意:FORBID_ATTR 是冗余防护,真正起效的是 ALLOWED_ATTR ——没列进去的属性一律被删,包括 style 和自定义 data- 属性(除非你明确加进列表)。
常见踩坑点:服务端 vs 前端调用差异
前端浏览器环境直接 import 就能用;Node.js 后端必须配 jsdom 模拟 DOM,否则 DOMPurify 报错。错误示例:ReferenceError: window is not defined。正确做法是:
- 安装
jsdom:npm install jsdom - 创建
JSDOM实例并传入DOMPurify工厂函数 - 禁用
runScripts: 'dangerously'——这个选项仅用于测试,生产环境必须设为false或不传
更关键的是:前端净化可被跳过(攻击者 curl 直发恶意 HTML 到 API),所以后端入库前必须再次调用 DOMPurify.sanitize()。两个环节缺一不可。
最易被忽略的一点:DOMPurify 默认不处理 URI 协议校验。如果允许 a[href],攻击者仍可填 javascript:alert(1)。必须配合 ALLOWED_URI_REGEXP 限制协议,例如:/^(https?|ftp|mailto):$/i。漏掉这条,等于白配。



















