您现在的位置是:亿华云 > 数据库
Sanitizer:给你的DOM消消毒
亿华云2025-10-03 06:31:49【数据库】2人已围观
简介大家好,我卡颂。业务中经常遇到需要处理「有风险的DOM」的场景,比如:各种工具的文本粘贴功能 需要渲染服务端返回HTML的场景 为了阻止潜在的XSS攻击,有两个选择:esc
大家好,消消我卡颂。消消
业务中经常遇到需要处理「有风险的消消DOM」的场景,比如:
各种工具的消消文本粘贴功能 需要渲染服务端返回HTML的场景为了阻止潜在的XSS攻击,有两个选择:
escape(转义) sanitize(消毒)本文会介绍这两者的消消区别以及为DOM消毒的API —— Sanitizer。
本文内容来自Safe DOM manipulation with the Sanitizer API[1]
转义与消毒
假设,消消我们想将这样一段HTML字符串插入DOM:
const str = "<img src= onerror=alert(0)>";如果直接将其作为某个元素的消消innerHTML,img的消消onerror回调执行JS代码的能力会带来XSS风险。
一种常见解决方案是消消:转义字符串。
什么是消消escape
浏览器会将一些保留字符解析为HTML代码,比如:
<被解析为标签的消消开头 >被解析为标签的云服务器提供商结尾 被解析为属性值的开头和结尾为了将这些保留字符显示为文本(不被解析为HTML代码),可以将其替换为对应的消消entity(HTML实体):
<的实体为< >的实体为> 的实体为"这种将HTML字符替换为entity的方式被称为escape(转义)
什么是sanitize
对于上面的HTML字符串:
const str = "<img src= onerror=alert(0)>";除了转义来规避XSS风险,还有一种更直观的消消思路:直接过滤掉onerror属性。
这种直接移除HTML字符串中有害的消消代码(比如<script>)的方式被称为sanitize(消毒)
需要用到一个API——Sanitizer[2]。
首先我们通过Sanitizer构造实例:
const sanitizer = new Sanitizer();调用实例的消消sanitizeFor方法,传入容器元素类型以及要消毒的HTML字符串:
sanitizer.sanitizeFor("div", str);会得到一个HTMLDivElement(即我们传入的容器元素类型),其内部包含一个没有onerror属性的img:
默认情况下Sanitizer会移除所有可能导致JS执行的代码。云服务器
丰富的配置
Sanitizer不仅开箱即用,还提供丰富的白名单、黑名单配置:
const config = { allowElements: [], blockElements: [], dropElements: [], allowAttributes: { }, dropAttributes: { }, allowCustomElements: true, allowComments: true }; new Sanitizer(config)比如,allowElements定义元素白名单,只有名单内的元素会被保留,与之对应的blockElements是元素黑名单:
const str = `hello <b><i>world</i></b>` new Sanitizer().sanitizeFor("div", str) // <div>hello <b><i>world</i></b></div> new Sanitizer({ allowElements: [ "b" ]}).sanitizeFor("div", str) // <div>hello <b>world</b></div> new Sanitizer({ blockElements: [ "b" ]}).sanitizeFor("div", str) // <div>hello <i>world</i></div> new Sanitizer({ allowElements: []}).sanitizeFor("div", str) // <div>hello world</div>allowAttributes是属性白名单,与之对应的dropAttributes是属性黑名单,对于如下配置:
{ allowAttributes: { "style": ["span"]}, dropAttributes: { "id": ["*"]}} }代表消毒后的HTML:
只允许span元素拥有style属性 移除所有元素(*通配符代表所有元素)的id属性兼容性
这么香的API兼容性怎么样呢:
当前只有在Chrome 93之后,开启试验标识后可使用:
about://flags/#enable-experimental-web-platform-features虽然原生Sanitizer离稳定还遥遥无期,但你可以使用DOMPurify[3]库实现类似功能。
后记
日常你更倾向使用escape还是sanitize呢?
参考资料
[1]Safe DOM manipulation with the Sanitizer API:
https://web.dev/sanitizer/
[2]Sanitizer:
https://wicg.github.io/sanitizer-api/
[3]DOMPurify:
https://github.com/cure53/DOMPurify
亿华云计算很赞哦!(76)