《前端之路》 之 前端 安全 XSS 原理以及防御手段
什么是 XSS
一、XSS
什么是 XSS

XSS,即 Cross Site Script , 翻译过来就是 跨站脚本攻击;为了和 css 有所区分,因而在安全领域被称为 XSS。
什么是 XSS 攻击

XSS 攻击指的是 攻击者在网站上注入恶意的客户端代码,通过恶意脚本对客户端网页进行篡改,从而在别的用户浏览网页的 时候,对用户进行控制或者获取 用户对隐私数据的 这么一种攻击手段。
XSS 攻击的方式 是什么
XSS 攻击可以分为3类:反射型(非持久型)、存储型(持久型)、基于DOM。
XSS攻击需要具备两个条件:需要向web页面注入恶意代码;这些恶意代码能够被浏览器成功的执行。
用户注入的 恶意脚本一般包括 JavaScript 、HTML、Flash。很多种的 XSS 攻击方式,但是共同点是: 将一些 隐私数据像:1、cookie、session 发送给攻击者。 2、将受害者重定向到一个由攻击者控制的网站(俗称钓鱼网站),在受害者的机器上进行一些恶意操作。
反射型(非持久型)的 XSS 攻击
XSS反射型攻击,恶意代码并没有保存在目标网站,而是通过引诱用户点击一个链接到目标网站的恶意链接来实施攻击的。
直接这么解释还是有点难懂的。下面,我们还是来看个 demo
<a href="http://127.0.0.1:1212/login/<img src='' onerror='alert(document.cookie)'>" target="_blank" >这是 XSS 的恶意链接</a>
假设某用户在黑客点钓鱼网站上 点击了这个 带有 XSS 攻击的恶意链接。就会跳转到 http://127.0.0.1:1212 这个网站上。刚好这个路径下的 链接是会有一个 发生一个 get 请求。
那么这个时候 <img src='' onerror='alert(document.cookie)'> 这部分的内容就被 当作 请求的 内容发送给了 服务端。如果服务端 为对该 内容进行 XSS 防御,直接返回给 浏览器。
那么这个时候就会出现 XSS 攻击了。<img src='' onerror='alert(document.cookie)'> 这句代码被显示在了 浏览器上,因为 img 标签也具有 跨域属性,直接执行了 onerror 中的 JS 代码。 黑客这个时候就可以 在目标网站上 为所欲为了。
比如这里就是 简单的 alert 了 所有的 cookie。但是,如果我是黑客的话,我肯定会把 用户的 cookie、localStorage、等等重要信息 全部上传到我的服务器,然后进行拿到各类想要的信息。从而获益。

存储型(持久型)的 XSS 攻击
存储型(持久型)的 XSS 攻击 和 反射型 其实也有异曲同工之妙呀。

这么多,我哪里记得住?
别慌,我们慢慢分析一波就都能记住啦~
恶意代码 通过表单提交的方式 被保存到目标网站的服务器中,这种攻击具有较强的稳定性和持久性,比较常见场景是在博客,论坛、OA、CRM等社交网站上,比如:某CRM系统的客户投诉功能上存在XSS存储型漏洞,黑客提交了恶意攻击代码,当系统管理员查看投诉信息时恶意代码执行,窃取了客户的资料,然而管理员毫不知情,这就是典型的XSS存储型攻击。

我们还是写个 demo 来方便 理解吧
<div><textarea id="textarea" class="text"></textarea></div>
<button id="btn" class="botton">submit</button>
大概就长这个样子了:

textarea 内则为 带有 xss 的代码,点击提交。直接 xhr 请求到 node 的服务端。
node 服务端 接收到 传入的参数 不做任何 xss 防御 直接保存起来的 js demo
一般是存储 sql 但是这里方便起见 我们就直接存 memory-cache ,代码如下:
router.post("/upload", (ctx, next) => {
let curData = JSON.stringify(ctx.request.body);
cache.put("xss", curData);
ctx.body = `<div>${curData}</div>`;
});
我们请求 一个新的路径来将 memory-cache 的值获取到。 node 端 代码:
router.get("/getName", (ctx, next) => {
let curData = cache.get("xss");
ctx.body = `<div>${JSON.parse(curData)}</div>`;
});
接下来就是访问 http://127.0.0.1:1212/getName
得到 如下 画面:

当然,黑客不会 alert 你的 cookie 信息。 直接 post 到 一个第三方的 服务器上,然后直接模拟浏览器访问,那就简直了。

基于 DOM 的 XSS 攻击
基于 DOM 的 XSS 攻击是指通过恶意脚本修改页面的 DOM 结构,是纯粹发生在客户端的攻击。
const divXss = document.getElementById("xss");
const xssbtn = document.getElementById("xssbtn");
const val = `'' onclick=alert(/xss/)`;
xssbtn.addEventListener("click", function() {
divXss.innerHTML = `<a href=${val}>testLink</a>`;
});
当然上面的这个
val往往是黑客 通过 input 或者 textarea 的 form表单提交引起的
当用户下意识的去点击 这个新增的 dom 的时候,就会出现 如下 场景:

黑客又可以为所欲为了。
二、XSS 的 防御
HttpOnly 防止劫取 Cookie
HttpOnly 最早由微软提出,至今已经成为一个标准。浏览器将禁止页面的Javascript 通过 document.cookie 获取带有 HttpOnly 属性的Cookie。
上文有说到,攻击者可以通过注入恶意脚本获取用户的 Cookie 信息。通常 Cookie 中都包含了用户的登录凭证信息,攻击者在获取到 Cookie 之后,则可以发起 Cookie 劫持攻击。所以,严格来说,HttpOnly 并非阻止 XSS 攻击,而是能阻止 XSS 攻击后的 Cookie 劫持攻击。
输入检查
不要相信用户的任何输入。 对于用户的任何输入要进行检查、过滤和转义。建立可信任的字符和 HTML 标签白名单,对于不在白名单之列的字符或者标签进行过滤或编码。
在 XSS 防御中,输入检查一般是检查用户输入的数据中是否包含 <,> 等特殊字符,如果存在,则对特殊字符进行过滤或编码,这种方式也称为 XSS Filter。
而在一些前端框架中,都会有一份 decodingMap, 用于对用户输入所包含的特殊字符或标签进行编码或过滤,如 <,>,script,防止 XSS 攻击:
// vuejs 中的 decodingMap
// 在 vuejs 中,如果输入带 script 标签的内容,会直接过滤掉
const decodingMap = {
'<': '<',
'>': '>',
'"': '"',
'&': '&',
'
': '\n'
}
输出检查
用户的输入会存在问题,服务端的输出也会存在问题。一般来说,除富文本的输出外,在变量输出到 HTML 页面时,可以使用编码或转义的方式来防御 XSS 攻击。
例如利用 sanitize-html 对输出内容进行有规则的过滤之后再输出到页面中。
本 demo 中的 koa 框架其实在输出的时候处理了标签:

这个时候 就会 减少 99% 的 xss 攻击了。是不是发现选择一款好的框架能节省好多的麻烦。
好了,这篇关于 XSS 的文章就介绍到 这里了,别着急 源码会放出来的。
全文的 demo 的源码地址: github源码地址
总结
一旦在DOM解析过程成出现不在预期内的改变,就有可能发生 XSS。
失控 就会出现 BUG。
防御手段 既然 攻防的人都知道了,那么自身代码的严谨程度就决定了整个项目的安度。
突然想起了 PDD ...
GitHub 地址:(欢迎 star 、欢迎推荐 : )
《前端之路》 之 前端 安全 XSS 原理以及防御手段的更多相关文章
- xss原理绕过防御个人总结
xss原理 xss产生的原因是将恶意的html脚本代码插入web页面,底层原理和sql注入一样,都是因为js和php等都是解释性语言,会将输入的当做命令执行,所以可以注入恶意代码执行我们想要的内容 x ...
- 《前端之路》- TypeScript (三) ES5 中实现继承、类以及原理
目录 一.先讲讲 ES5 中构造函数(类)静态方法和多态 1-1 JS 中原型以及原型链 例子一 1-2 JS 中原型以及原型链中,我们常见的 constructor.prototype.**prot ...
- 前端安全(XSS、CSRF防御)
一.网络安全 OWASP:开放式Web应用程序安全项目(OWASP,Open Web Application Security Project) OWASP是一个开源的 ...
- 《前端之路》之 Javascript 模块化管理的来世今生
目录 第二章 - 04: Javascript 模块化管理的来世今生 一.什么是模块化开发 1-1.模块化第一阶段 1-2.封装到对象 1-3. 对象的优化 二.模块化管理的发展历程 2-1.Comm ...
- 《前端之路》- TypeScript (四) class 中各类属性、方法,抽象类、多态
目录 一.TypeScript 中的类 二.TypeScript 中类的继承 三.TypeScript 中公共,私有与受保护的修饰符 3-1.属性的 public 3-2.属性的 private 3- ...
- jQuery延迟加载(懒加载)插件 – jquery.lazyload.js-Web前端(W3Cways.com) - Web前端学习之路
Lazy Load 是一个用 JavaScript 编写的 jQuery 插件. 它可以延迟加载长页面中的图片. 在浏览器可视区域外的图片不会被载入, 直到用户将页面滚动到它们所在的位置. 这与图片预 ...
- 《前端之路》之二:数据类型转换 && 隐式转换 || 显式转换
目录 02:数据类型转换 && 隐式转换 || 显式转换 02:数据类型转换 && 隐式转换 || 显式转换 在上一个章节中,我们介绍了 JavaScript 的基本的 ...
- 《前端之路》--- 重温 Egg.js
目录 <前端之路>--- 重温 Egg.js 一.基础功能 > 日志系统包含了 四大层面的 日志对象, 分别是 App Logger.App CoreLogger.Context L ...
- 《前端之路》- TypeScript(二) 函数篇
目录 一.定义函数方法 二.定义函数传参 三.可选传参 四.默认传参 五.传递剩余参数 六.函数重载 七.箭头函数 八.总结 一.定义函数方法 在 es5 中定时函数的方法有 命名函数和函数表达式(匿 ...
随机推荐
- Python测试远程端口连接时间
问题 最近自己服务器访问别人的服务器,有时候会报超时错误,有时候又能够正常访问别人服务器. 思路 最开始猜测是网络不稳定造成的,但是自己没有收集什么时候超时,什么时候能正常访问别人服务器的日志,搞网络 ...
- jdk和tomcat环境配置
一.安装JDK和Tomcat 1,安装JDK:直接运行jdk-7-windows-i586.exe可执行程序,默认安装即可. 备注:路径可以其他盘符,不建议路径包含中文名及特殊符号. 2.安装Tomc ...
- JS入门熟知
JS是面向对象的语言 封装 继承 多态 聚集(对象中具有引用其他对象的能力) JS使用中绝大多数情况不需要进行面向对象的设计,很多情况是使用已经设计好,准备好的对象,基于对象的语言. JS的使用(引入 ...
- 连接Access数据遇到的问题总览!
由于要访问一个厂商的access数据,所以要写一个对于access的demo,相对于mysql.sqlserver来说,连接access花费了不少精力,现在将遇到的问题分享出来,以后大家遇到类似问题时 ...
- ElasticSearch本地调测环境构建
ElasicSearch版本:6.0.0:https://github.com/elastic/elasticsearch.git 1:安装JVM(JVM1.8以上) 2:安装gradle(3.3以上 ...
- 单片机开发——01工欲善其事必先利其器(Keil软件安装破解)
本文是博主<单片机开发>博客第一篇文章,主要讲述51单片机编程软件Keil uVision4的安装及破解过程. 1. Keil uVision4安装包文件 PATH:链接 ...
- python之字典、列表、元组生成器的使用
python的生成式在一些类型相互转换的时候可以写出十分优雅的代码.如列表转换成另一个列表.字典.或元组.并且代码的执行效率也比使用for...in...循环高. 列表生成式 列表生成式即生成列表的生 ...
- Mysql 查询缓存总结
Mysql 查询缓存总结 MySQL查询缓存解释 缓存完整的SELECT查询结果,也就是查询缓存.保存查询返回的完整结果.当查询命中该缓存,mysql会立刻返回结果,跳过了解析.优化和执行阶段, 查询 ...
- JSP中的隐含对象
什么是JSP中隐含对象:容器自动创建,在JSP文件中可以直接使用的对象. 作用:JSP预先创建的这些对象可以简化对HTTP的请求,响应信息的访问. JSP中的隐含对象: 输入输出对象:request. ...
- datePicker.js 应用
var calendar2 = new datePicker();calendar.init({ 'trigger': '#datetime-picker-start', /*选择器,触发弹出插件*/ ...