JavaScript Sanitizer API:原生WEB安全API出现啦
10月18号, W3C中网络平台孵化器小组(Web Platform Incubator Community Group)公布了HTML Sanitizer API的规范草案。这份草案用来解决浏览器如何解决XSS攻击问题。
网络安全中比较让开发者们头疼的一类是XSS跨站点脚本攻击。这种攻击通常指的是通过利用网页开发时留下的漏洞,即将恶意指令代码注入到网页,使用户加载并执行攻击者恶意制造的网页程序。
这些恶意代码没有经过过滤,与网站的正常代码混在一起,浏览器无法分辨哪些内容是可信的,恶意脚本就会被执行。而XSS攻击的核心有两个步骤:1、处理攻击者提交恶意代码;2、浏览器执行恶意代码。
为了解决在这两步恶意攻击中解决这个问题,通常有以下手段,
- 增加过滤条件
- 只进行纯前端行渲染,将数据和代码内容分开
- 对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出现啦的更多相关文章
- [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 ...
- H5的Web Audio Api
概述 研究Web Audio Api的主要原因是:工作中需要在ios中实现声音的淡出效果,主要是通过setInterval来改audio标签的volume属性实现的,但是ios上面volume属性是只 ...
- BMap:WEB 服务API
ylbtech-Map-Baidu: WEB 服务API 百度地图Web服务API为开发者提供http/https接口,即开发者通过http/https形式发起检索请求,获取返回json或xml格式的 ...
- Web Audio API之手把手教你用web api处理声音信号:可视化音乐demo
1.Web Audio API 介绍 Web Audio API 提供了在Web上控制音频的一个非常有效通用的系统 ,这些通用系统通俗的讲就是我们可以利用Web Audio API提供的各种方法操作各 ...
- 【Web Audio API】 — 那些年的 web audio
转 TAT.Jdo:[Web Audio API] - 那些年的 web audio 这主题主要是早期对 web audio api的一些尝试,这里整理一下以便以后翻阅,如有错误,诚请指正. 在这之前 ...
- JavaScript常见原生DOM操作API总结
[TOC] 最近面试的时候被这个问题给卡了,所以抽时间好好复习一下. 几种对象 Node Node是一个接口,中文叫节点,很多类型的DOM元素都是继承于它,都共享着相同的基本属性和方法.常见的Node ...
- JavaScript原生DOM操作API总结
最近面试的时候被这个问题给卡了,所以抽时间好好复习一下. 原文:http://www.cnblogs.com/liuxianan/p/javascript-dom-api.html 几种对象 Node ...
- HTML5权威指南--Web Storage,本地数据库,本地缓存API,Web Sockets API,Geolocation API(简要学习笔记二)
1.Web Storage HTML5除了Canvas元素之外,还有一个非常重要的功能那就是客户端本地保存数据的Web Storage功能. 以前都是用cookies保存用户名等简单信息. 但是c ...
- 【HTML5】Web Audio API打造超炫的音乐可视化效果
HTML5真是太多炫酷的东西了,其中Web Audio API算一个,琢磨着弄了个音乐可视化的demo,先上效果图: 项目演示:别说话,点我! 源码已经挂到github上了,有兴趣的同学也可以去st ...
随机推荐
- AtCoder Beginner Contest 224
AtCoder Beginner Contest 224 A - Tires 思路分析: 判断最后一个字符即可. 代码如下: #include <bits/stdc++.h> using ...
- seata整合多数据源
seata整合多数据源 一.背景 二.整合步骤 1.seata server的搭建 2.引入数据源切换组件 3.引入seata组件 4.配置多数据源 5.关闭seata自己默认的数据源代理 6.配置s ...
- 攻防世界 web2.robots
输入ip/robots.txt,显示出了flag目录,直接访问.
- C++STL(set……)
set 底层实现是用红黑树. set 建立 set<int> s; // 不可重,默认升序 set<int,less> s; // 不可重,升序 set<int,grea ...
- (转载)关于Linux C函数strtok的使用要点
今天遇到了处理字符串的问题,比如分割问题,但是一时间想不起来什么方法,也不想手写一个类似java String中的split函数,于是百度了一下,发现了strtok这个好用的方法,以此作为总结. st ...
- simulate_screencap
#!/bin/bashadb shell screencap -p /sdcard/screen.pngadb pull /sdcard/screen.png ./adb shell rm /sdca ...
- MySql表、约束、视图
MySql表.约束.视图 索引组织表 在InnoDB存储引擎中,表都是根据主键顺序组织存放的,这种存储方式的表成为索引组织表(index organized table). 每张表都有主键,如果创建表 ...
- docker 加入域名
先运行docker镜像 # 进入 docker 容器 mynginx 是容器名 docker exec -i -t mynginx /bin/bash #安装vim apt-get install v ...
- Maven settings配置阿里镜像
一般只用配置三个地方 maven仓库路径 镜像 默认JDK版本 <?xml version="1.0" encoding="UTF-8"?> < ...
- PTA 7-4 最小生成树的唯一性 (35分)
PTA 7-4 最小生成树的唯一性 (35分) 给定一个带权无向图,如果是连通图,则至少存在一棵最小生成树,有时最小生成树并不唯一.本题就要求你计算最小生成树的总权重,并且判断其是否唯一. 输入格式: ...