10月18号, W3C中网络平台孵化器小组(Web Platform Incubator Community Group)公布了HTML Sanitizer API的规范草案。这份草案用来解决浏览器如何解决XSS攻击问题。

网络安全中比较让开发者们头疼的一类是XSS跨站点脚本攻击。这种攻击通常指的是通过利用网页开发时留下的漏洞,即将恶意指令代码注入到网页,使用户加载并执行攻击者恶意制造的网页程序。

这些恶意代码没有经过过滤,与网站的正常代码混在一起,浏览器无法分辨哪些内容是可信的,恶意脚本就会被执行。而XSS攻击的核心有两个步骤:1、处理攻击者提交恶意代码;2、浏览器执行恶意代码。

为了解决在这两步恶意攻击中解决这个问题,通常有以下手段,

  1. 增加过滤条件
  2. 只进行纯前端行渲染,将数据和代码内容分开
  3. 对HTML充分转义

以上手段这些步骤繁琐,需要注意的内容也很多。为了让开发者更加便捷地解决XSS攻击的问题,浏览器现提供了原生的XSS攻击消毒能力。

HTML Sanitizer API——这份由谷歌、Mozilla和Cure53联手发起提供的API即将最终完成,通过这个浏览器原生API我们可以更加轻松地保护Web应用程序免受XSS的攻击。

接下来我们一起来了解一下这个安全API吧。

Sanitizer API简介

Sanitizer API可以让浏览器直接从网站动态更新的标记中删除恶意代码。当有恶意HTML字符串、和文档或文档片段对象想插入现有DOM之中,我们可以使用HTML Sanitizer API直接将这些内容清理。有点像电脑的安全卫士应用,可以清除风险内容。

使用Sanitizer API有以下三个优点:

  • 减少Web应用程序中跨站点脚本的攻击次数
  • 保证HTML输出内容在当前用户代理中安全使用
  • Sanitizer API 的可用性很强

Sanitizer API的特性

Sanitizer API为HTML字符串安全打开新世界大门,将所有的功能大致分类,可以分为以下三个主要特性:

1.对用户输入进行杀毒

Sanitizer API的主要功能是接受字符串并将其转换为更安全的字符串。这些转换后的字符串不会执行额外的JavaScript,并确保应用程序受到XSS攻击的保护。

2.浏览器内置

该库在浏览器安装的时候一同预装,并在发现bug或出现新的攻击时进行更新。相当于我们的浏览器有了内置的杀毒措施,无需导入任何外部库。

3.使用简洁安全

在使用了Sanitizer API之后,浏览器此时就有了一个强大又安全的解析器,作为一个成熟的浏览器,它知道如何处理DOM中每个元素的活动。相比之下,用JavaScript开发的外部解析器不仅成本高昂,同时很容易跟不上前端大环境的更新速度。

说完了这些使用上的亮点特性,让我们一起来看看这个API的具体用法。

Sanitizer API的使用

Sanitizer API使用Sanitizer()方法构造函数,Sanitizer类进行配置。

官方提供了三种基础清理方式:

1、清理隐藏上下文的字符串

Element.setHTML() 用于解析和清理字符串,并立即将其插入DOM,这个方法适用于目标DOM元素已知且HTML内容为字符串的情况。

const $div = document.querySelector('div')
const user_input = `<em>Hello There</em><img src="" onerror=alert(0)>` // The user string.
const sanitizer = new Sanitizer() // Our Sanitizer
// We want to insert the HTML in user_string into a target element with id
// target. That is, we want the equivalent of target.innerHTML = value, except
// without the XSS risks.
$div.setHTML(user_input, sanitizer) // <div><em>Hello There</em><img src=""></div>

2、清理给定上下的文字符串

Sanitizer.sanitizeFor() 用于解析、清理和准备稍后准备添加到DOM中的字符串。

适用于HTML内容是字符串,并且目标DOM元素类型已知(例如div、span)的情况。

const user_input = `<em>Hello There</em><img src="" onerror=alert(0)>`
const sanitizer = new Sanitizer()
// Later:
// The first parameter describes the node type this result is intended for.
sanitizer.sanitizeFor("div", user_input) // HTMLDivElement <div>

需要注意的是, HTMLElement中 .innerHTML 的清理输出结果是字符串格式。

sanitizer.sanitizeFor("div", user_input).innerHTML // <em>Hello There</em><img src="">

3、清理请理节点

对于已经有用户控制的DocumentFragment,Sanitizer.sanitize()可以直接对DOM树节点进行清理。

// Case: The input data is available as a tree of DOM nodes.
const sanitizer = new Sanitizer()
const $userDiv = ...;
$div.replaceChildren(s.sanitize($userDiv));

除了以上提到的三种方式之外,SanitizerAPI通过删除和、过滤属性和标记来修改HTML字符串。

举个“栗子”。

  • 删除某些标记(script, marquee, head, frame, menu, object, etc.)并保留content标签。
  • 移除大多属性,只保留<a>标签和colspanson<td>,<th>标签上的HREF。
  • 筛选出可能导致风险脚本执行的内容。

默认设置中,这个安全API只用来防止XSS的出现。但是一些情况下我们也需要自定义自义设置,下面介绍一些常用的配置。

自定义消毒

创建一个配置对象,并在初始化Sanitizer API时将其传递给构造函数。

const config = {
allowElements: [],
blockElements: [],
dropElements: [],
allowAttributes: {},
dropAttributes: {},
allowCustomElements: true,
allowComments: true
};
// sanitized result is customized by configuration
new Sanitizer(config)

下面是一些常用方法:

  • allowElements 对指定输入进行保留
  • blockElements blockElements 删除内容中需要保留的部分
  • dropElements dropElements 删除指定内容,包括输入的内容
const str = `hello <b><i>there</i></b>`

new Sanitizer().sanitizeFor("div", str)
// <div>hello <b><i>there</i></b></div> new Sanitizer({allowElements: [ "b" ]}).sanitizeFor("div", str)
// <div>hello <b>there</b></div> new Sanitizer({blockElements: [ "b" ]}).sanitizeFor("div", str)
// <div>hello <i>there</i></div> new Sanitizer({allowElements: []}).sanitizeFor("div", str)
// <div>hello there</div>
  • allowAttributes和dropAttributes这两个参数可以自定义需要保留或者需要删除的部分。
const str = `<span id=foo class=bar style="color: red">hello there</span>`

new Sanitizer().sanitizeFor("div", str)
// <div><span id="foo" class="bar" style="color: red">hello there</span></div> new Sanitizer({allowAttributes: {"style": ["span"]}}).sanitizeFor("div", str)
// <div><span style="color: red">hello there</span></div> new Sanitizer({dropAttributes: {"id": ["span"]}}).sanitizeFor("div", str)
// <div><span class="bar" style="color: red">hello there</span></div>
  • AllowCustomElements开启是否使用自定义元素
const str = `<elem>hello there</elem>`

new Sanitizer().sanitizeFor("div", str);
// <div></div> new Sanitizer({ allowCustomElements: true,
allowElements: ["div", "elem"]
}).sanitizeFor("div", str);
// <div><elem>hello there</elem></div>

如果没有进行任何配置,会直接使用默认配置内容。

这个API看起来能为我们解决不小少的问题,但是现在浏览器对其的支持还有限,更多功能还在持续完善中。我们也很期待看到功能更加完善的SanitizerAPI

对它感兴趣的小伙伴在Chrome93+中可以通过about://flags/#enable-experimental-web-platform-features启用,Firefox中目前也在实验阶段,可以在about:config将dom.security.sanitizer.enabled 设为true来启用。

了解更多内容可以查看:https://developer.mozilla.org/en-US/docs/Web/API/HTML_Sanitizer_API

关于数据安全的担忧

根据 Verizon 2020 年数据泄露调查报告(Verizon Business,2020 年)显示,约90% 的数据泄露事件是由于跨站点脚本((XSS))和安全漏洞造成的。对于前端开发者而言,面对越发频繁的网络攻击,除了借助Sanitizer API等安全机制外,还可以考虑使用"数据与代码分离"的SpreadJS等前端表格控件。

JavaScript Sanitizer API:原生WEB安全API出现啦的更多相关文章

  1. [Javascript] Intro to the Web Audio API

    An introduction to the Web Audio API. In this lesson, we cover creating an audio context and an osci ...

  2. H5的Web Audio Api

    概述 研究Web Audio Api的主要原因是:工作中需要在ios中实现声音的淡出效果,主要是通过setInterval来改audio标签的volume属性实现的,但是ios上面volume属性是只 ...

  3. BMap:WEB 服务API

    ylbtech-Map-Baidu: WEB 服务API 百度地图Web服务API为开发者提供http/https接口,即开发者通过http/https形式发起检索请求,获取返回json或xml格式的 ...

  4. Web Audio API之手把手教你用web api处理声音信号:可视化音乐demo

    1.Web Audio API 介绍 Web Audio API 提供了在Web上控制音频的一个非常有效通用的系统 ,这些通用系统通俗的讲就是我们可以利用Web Audio API提供的各种方法操作各 ...

  5. 【Web Audio API】 — 那些年的 web audio

    转 TAT.Jdo:[Web Audio API] - 那些年的 web audio 这主题主要是早期对 web audio api的一些尝试,这里整理一下以便以后翻阅,如有错误,诚请指正. 在这之前 ...

  6. JavaScript常见原生DOM操作API总结

    [TOC] 最近面试的时候被这个问题给卡了,所以抽时间好好复习一下. 几种对象 Node Node是一个接口,中文叫节点,很多类型的DOM元素都是继承于它,都共享着相同的基本属性和方法.常见的Node ...

  7. JavaScript原生DOM操作API总结

    最近面试的时候被这个问题给卡了,所以抽时间好好复习一下. 原文:http://www.cnblogs.com/liuxianan/p/javascript-dom-api.html 几种对象 Node ...

  8. HTML5权威指南--Web Storage,本地数据库,本地缓存API,Web Sockets API,Geolocation API(简要学习笔记二)

    1.Web Storage HTML5除了Canvas元素之外,还有一个非常重要的功能那就是客户端本地保存数据的Web Storage功能. 以前都是用cookies保存用户名等简单信息.   但是c ...

  9. 【HTML5】Web Audio API打造超炫的音乐可视化效果

    HTML5真是太多炫酷的东西了,其中Web Audio API算一个,琢磨着弄了个音乐可视化的demo,先上效果图: 项目演示:别说话,点我!  源码已经挂到github上了,有兴趣的同学也可以去st ...

随机推荐

  1. VUE中v-for更新检测

    口诀: 数组变更方法,就会导致 v-for 更新,页面更新 数组非变更方法:返回新数组,就不会导致 v-for 更新,更新值检测不到可采用覆盖或者 this.$set() 数组变更方法如下: 1. a ...

  2. Spark解决SQL和RDDjoin结果不一致问题(工作实录)

    问题描述:DataFrame的join结果不正确,dataframeA(6000无重复条数据) join dataframeB(220条无重复数据,由dataframeA转化而来,key值均源于dat ...

  3. 攻防世界 杂项 9.a_good_idea

    题目描述: 汤姆有个好主意 解题思路: 首先按照隐写思路找了一下没找到flag,接着使用winhex打开图片,发现图片里面又包含了一张图片,然后马上改了一下后缀为zip, 解压后发现里面有:hint. ...

  4. 痞子衡嵌入式:超级下载算法RT-UFL v1.0在Segger Ozone下的使用

    痞子衡主导的"学术"项目 <RT-UFL - 一个适用全平台i.MXRT的超级下载算法设计> v1.0 版发布近 4 个月了,部分客户已经在实际项目开发调试中用上了这个 ...

  5. 『学了就忘』Linux基础 — 13、Linux系统的分区和格式化

    目录 1.Linux系统的分区 (1)磁盘分区定义 (2)两种分区表形式 (3)MBR分区类型 2.Linux系统的格式化 (1)格式化定义 (2)格式化说明 1.Linux系统的分区 (1)磁盘分区 ...

  6. Spring Cloud 微服务实战——nacos 服务注册中心搭建(附源码)

    作为微服务的基础功能之一的注册中心担任重要的角色.微服务将单体的服务拆分成不同的模块下的服务,而不同的模块的服务如果进行通信调用呢?这就需要服务注册与发现.本文将使用阿里开源项目 nacos 搭建服务 ...

  7. IM服务器:开发一个高并发的IM服务器难在哪

    IM服务器要实现的最基本功能就是消息的转发.--好像是一句废话! 这就意味着IM服务器要为每个登录用户创建一个与该用户信息相关的内存上下文,为方便描述我们在这里称之为:user_context.use ...

  8. Device /dev/sdb excluded by a filter

    原因是添加的磁盘是在另一个虚拟机中新建的,已经有了分区表,现在的虚拟机并不能识别磁盘的分区表,运行parted命令重做分区表,中途需要输入三次命令(mklabel msdos -> yes-&g ...

  9. C# StringBuilder和string

    StringBuilder和string 1.string是引用类型还是值类型 MSDN官方说string是引用类型: 引用类型:引用分配栈内存,引用类型本身的数据存储在堆中: 值类型:在函数中创建, ...

  10. Java8新特性Stream流应用示例

    Java8新特性介绍 过滤集合 List<String> newList = list.stream().filter(item -> item != null).collect(C ...