不能靠正则匹配on\w+=清事件属性,因为HTML是上下文敏感语言,正则易误删注释/换行/伪属性(如data-on-click)、破坏data-v-xxx等框架属性;唯一可靠路径是querySelectorAll遍历后用removeAttribute('onclick')等精准移除。

HTML 属性清理不是“删掉所有可疑东西”,而是按语义层级做有依据的裁剪:标签级放行、属性级验证、值级过滤。直接用正则或 innerHTML 赋值,大概率破坏结构或漏掉 XSS 向量。
为什么不能靠正则匹配 on\w+= 清事件属性
正则看似快,但 HTML 是上下文敏感语言,不是纯文本。常见失效场景:
-
onerror出现在注释里:<!-- onerror="xss()" -->,正则会误删 - 换行或空格分隔:
onclick\n=\n"alert(1)"会让/on\w+\s*=\s*["'][^"']*["']/gi失效 - 伪属性干扰:
data-on-click或x-on:click(Vue/Alpine)会被误杀 - 服务端渲染注入的
data-v-xxx属性可能被正则连带破坏,导致框架失活
removeAttribute() 必须配合 querySelectorAll 遍历
DOM 操作才是唯一可靠路径,因为只有浏览器解析器知道哪些是真实存在的事件属性节点:
- 匹配要全:至少覆盖
['onclick','onsubmit','onchange','onload','onerror','onfocus','onblur','onkeydown','oninput','onpaste','oncut'] - 调用要准:必须用完整小写属性名,
el.removeAttribute('onclick')有效,el.removeAttribute('click')无效 - 顺序无关紧要,但建议先清事件属性再处理
style和class,避免样式残留干扰后续判断 - 动态插入的内容(如
insertAdjacentHTML)不会自动触发该逻辑,需在插入前清洗或监听DOMNodeInserted(不推荐)或 MutationObserver
白名单机制比黑名单更安全,但配置有陷阱
像 sanitize-html 或 ponytail 这类工具依赖白名单,但实际配置时容易忽略三类边界:
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
立即学习“前端免费学习笔记(深入)”;
-
allowedAttributes若设为['*'],等于放行所有属性,包括src、href中的javascript:协议——必须配合allowedSchemes限制 URL 协议 -
allowedTags允许iframe但没配iframeAllow,会导致 sandbox 绕过 - 某些属性(如
contenteditable)虽不在事件属性列表里,但开启后可触发execCommand类 XSS,需显式禁止
清理后 DOM 序列化仍可能暴露空属性
比如用 classList.remove() 清完所有类,class 属性不会消失,而是变成 class="" 或 class(无值)。这本身合规,但要注意:
-
[class]CSS 选择器仍能匹配它,可能意外触发样式规则 -
getAttribute('class')返回空字符串,但hasAttribute('class')仍为true - 若需彻底移除,得手动调用
removeAttribute('class'),不能依赖 classList 接口 - 同理适用于
id、style等全局属性:清空值 ≠ 删除属性
真正难的不是“怎么删”,而是“删完是否还可信”——比如 data-* 属性虽安全,但若后端把它当执行上下文传给 JS 模板引擎,就又成了注入点。清理永远只是纵深防御的一环,源头约束和运行时沙箱缺一不可。


















