《前端之路》 之 前端 安全 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 中定时函数的方法有 命名函数和函数表达式(匿 ...
随机推荐
- C++中,用类和重载运算符写高精模板
先放代码: #include<iostream> #include<cstdio> #include<cstring> using namespace std; s ...
- CSS学习笔记3:选择器及优先级
CSS选择器的类型: 标签选择器 类选择器 ID选择器 全局选择器 群组选择器 后代选择器 1.标签选择器: 以HTML的标签作为选择器,凡是选择了一个标签,那么所有这个标签的内容都是用了 ...
- 【Android学习笔记】Android Studio简单断点调试
首先点击断点调试按钮运行App 启动之后,会弹出如下图的提示框,不要管,几秒之后这个弹框会自动消失,然后App会成功运行. 下面介绍一下断点调试的相关操作按钮对应的功能: 按钮1的功能:从当前断点跳到 ...
- MySQL性能调优——锁定机制与锁优化分析
针对多线程的并发访问,任何一个数据库都有其锁定机制,它的优劣直接关系着数据的一致完整性与数据库系统的高并发处理性能.锁定机制也因此成了各种数据库的核心技术之一.不同数据库存储引擎的锁定机制是不同的,本 ...
- Swagger使用教程大全,从入门到精通
Swagger是遵守OpenAPI规范(OAS)的世界上最大的API框架开发工具,可在整个API生命周期内进行开发,从设计和文档到测试和部署.它提供了许多试用的工具来帮助开发者进行接口开发,如及时接口 ...
- Nginx虚拟主机
[root@Nginx-server ~]# tar zxvf nginx-1.11.2.tar.gz [root@Nginx-server ~]# useradd -M -s /sbin/nolog ...
- KVM内核文档阅读笔记
KVM在内核中有丰富的文档,位置在Documentation/virtual/kvm/. 00-INDEX:整个目录的索引及介绍文档. api.txt:KVM用户空间API,所谓的API主要是通过io ...
- client,server,nginx 在使用keepAlive 专题
2. TCP keepalive overview In order to understand what TCP keepalive (which we will just call keepali ...
- 【转】linux系统中如何进入退出vim编辑器,方法及区别
在linux家族中,vim编辑器是系统自带的文本编辑器,其功能强大自不必说了. 偶有小白,刚接触linux,要修改某个文本文件,不可能像WINDOWS那样操作,更有甚者,进入VI编辑器后,无法退出以致 ...
- redhad安装gcc问题---解决依赖问题
在安装gcc时需要cpp和cloog-ppl 但是在安装cpp的时候需要这个依赖: libmpfr.so.1()(64bit) is needed by cpp-4.4.6-3.el6.x86_64 ...