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. LDAP-初见

    目录 什么是LDAP? LDAP 协议能解决什么问题? Spring Boot中使用LDAP来统一管理用户信息 添加用户 连接LDAP服务端 什么是LDAP? LDAP 的全称是 Lightweigh ...

  2. DOM的本质 和 方法

    <JavaScript DOM编程艺术> 读书笔记 一句话解释DOM: DOM,即我们所看到的网页,其在浏览器背后的文档结构(树状分支结构),涵盖了每一个节点(称之为对象).可以通过JS等 ...

  3. js判断移动端浏览器类型,微信浏览器、支付宝小程序、微信小程序等

    起因 现在市场上各种跨平台开发方案百家争鸣各有千秋,个人认为最成熟的还是hybird方案,简单的说就是写H5各种嵌入,当然作为前端工程师最希望的也就是公司采用hybird方案当作技术路线. 所谓的hy ...

  4. Convolutional Neural Network-week1编程题(一步步搭建CNN模型)

    Convolutional Neural Networks: Step by Step implement convolutional (CONV) and pooling (POOL) layers ...

  5. cunda 常用命令,删除,创建,换源

    https://github.com/tensorflow/tensorflow/ conda create --name [虚拟环境名] python=3.7 创建一个环境 conda activa ...

  6. 从浏览器发送请求给SpringBoot后端时,是如何准确找到哪个接口的?(下篇)

    纸上得来终觉浅,绝知此事要躬行 注意: 本文 SpringBoot 版本为 2.5.2; JDK 版本 为 jdk 11. 前言: 前文:你了解SpringBoot启动时API相关信息是用什么数据结构 ...

  7. 通过简单例子 | 快速理清 UML 中类与类的六大关系

    关于封面:我想我们都会离开 类与类之间的六大关系 泛化 ( Generalization ) ---> 表继承关系 实现 ( Realization ) 关联 ( Association ) 聚 ...

  8. RogrePirates Scrum Meeting 博客汇总

    RogrePirates 博客目录 一.Scrum Meeting 1.Alpha阶段 第一次会议 第二次会议 第三次会议 第四次会议 第五次会议 第六次会议 第七次会议 第八次会议 第九次会议 第十 ...

  9. [技术博客] Django中文件的保存与访问

    [技术博客] Django中文件的保存与访问 在TextMarking项目开发中,数据库需要保存用户上传的文本文档. 原型设计:用户点击上传文本->保存文本->文本发送到后端保存为文件. ...

  10. InitSpatialMetaData()速度慢的问题

    解决方法:with sqlite3.connect(dbfile) as con: con.enable_load_extension(True) con.execute("SELECT l ...