XSS定义

XSS, 即为(Cross Site Scripting), 中文名为跨站脚本, 是发生在目标用户的浏览器层面上的,当渲染DOM树的过程成发生了不在预期内执行的JS代码时,就发生了XSS攻击。

跨站脚本的重点不在‘跨站’上,而在于‘脚本’上。大多数XSS攻击的主要方式是嵌入一段远程或者第三方域上的JS代码。实际上是在目标网站的作用域下执行了这段js代码。

XSS攻击方式

反射型 XSS

反射型XSS,也叫非持久型XSS,是指发生请求时,XSS代码出现在请求URL中,作为参数提交到服务器,服务器解析并响应。响应结果中包含XSS代码,最后浏览器解析并执行。

从概念上可以看出,反射型XSS代码是首先出现在URL中的,然后需要服务端解析,最后需要浏览器解析之后XSS代码才能够攻击。

举一个小栗子。

使用express起一个web服务器,然后设置一下请求接口。通过ajax的GET请求将参数发往服务器,服务器解析成json后响应。将返回的数据解析后显示到页面上。(没有对返回的数据进行解码和过滤等操作。)

html
<textarea name="txt" id="txt" cols="80" rows="10">
<button type="button" id="test">测试</button> js
var test = document.querySelector('#test')
test.addEventListener('click', function () {
var url = `/test?test=${txt.value}` // 1. 发送一个GET请求
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if ((xhr.status >= 200 && xhr.status <) || xhr.status === 304) {
// 3. 客户端解析JSON,并执行
var str = JSON.parse(xhr.responseText).test
var node = `${str}`
document.body.insertAdjacentHTML('beforeend', node)
} else {
console.log('error', xhr.responseText)
}
}
}
xhr.open('GET', url, true)
xhr.send(null)
}, false) express
var express = require('express');
var router = express.Router(); router.get('/test', function (req, res, next) {
// 2. 服务端解析成JSON后响应
res.json({
test: req.query.test
})
})

现在我们通过给textarea添加一段有攻击目的的img标签,

<img src="null" onerror='alert(document.cookie)' />

实际的页面时这样的。

ok现在,我们点击<测试>按钮,一个XSS攻击就发生了。下面图片中是获取了本地的部分cookie信息

实际上,我们只是模拟攻击,通过alert获取到了个人的cookie信息。但是如果是黑客的话,他们会注入一段第三方的js代码,然后将获取到的cookie信息存到他们的服务器上。这样的话黑客们就有机会拿到我们的身份认证做一些违法的事情了。

以上,存在的一些问题,主要在于没有对用户输入的信息进行过滤,同时没有剔除掉DOM节点中存在的一些有危害的事件和一些有危害的DOM节点。

存储型 XSS
存储型XSS,也叫持久型XSS,主要是将XSS代码发送到服务器(不管是数据库、内存还是文件系统等。),然后在下次请求页面的时候就不用带上XSS代码了。

最典型的就是留言板XSS。用户提交了一条包含XSS代码的留言到数据库。当目标用户查询留言时,那些留言的内容会从服务器解析之后加载出来。浏览器发现有XSS代码,就当做正常的HTML和JS解析执行。XSS攻击就发生了。
DOM XSS
DOM XSS攻击不同于反射型XSS和存储型XSS,DOM XSS代码不需要服务器端的解析响应的直接参与,而是通过浏览器端的DOM解析。这完全是客户端的事情。

DOM XSS代码的攻击发生的可能在于我们编写JS代码造成的。我们知道eval语句有一个作用是将一段字符串转换为真正的JS语句,因此在JS中使用eval是很危险的事情,容易造成XSS攻击。避免使用eval语句。

如以下代码

test.addEventListener('click', function () {
var node = window.eval(txt.value)
window.alert(node)
}, false) txt中的代码如下
<img src='null' onerror='alert(123)' />

以上通过eval语句就造成了XSS攻击。

XSS危害

  1. 通过document.cookie盗取cookie
  2. 使用js或css破坏页面正常的结构与样式
  3. 流量劫持(通过访问某段具有window.location.href定位到其他页面)
  4. Dos攻击:利用合理的客户端请求来占用过多的服务器资源,从而使合法用户无法得到服务器响应。
  5. 利用iframe、frame、XMLHttpRequest或上述Flash等方式,以(被攻击)用户的身份执行一些管理动作,或执行一些一般的如发微博、加好友、发私信等操作。
  6. 利用可被攻击的域受到其他域信任的特点,以受信任来源的身份请求一些平时不允许的操作,如进行不当的投票活动。

XSS防御

从以上的反射型和DOM XSS攻击可以看出,我们不能原样的将用户输入的数据直接存到服务器,需要对数据进行一些处理。以上的代码出现的一些问题如下

  1. 没有过滤危险的DOM节点。如具有执行脚本能力的script, 具有显示广告和色情图片的img, 具有改变样式的link, style, 具有内嵌页面的iframe, frame等元素节点。
  2. 没有过滤危险的属性节点。如事件, style, src, href等
  3. 没有对cookie设置httpOnly。

如果将以上三点都在渲染过程中过滤,那么出现的XSS攻击的概率也就小很多。

解决方法如下

对cookie的保护

  1. 对重要的cookie设置httpOnly, 防止客户端通过document.cookie读取cookie。服务端可以设置此字段。

对用户输入数据的处理

  1. 编码:不能对用户输入的内容都保持原样,对用户输入的数据进行字符实体编码。对于字符实体的概念可以参考文章底部给出的参考链接。
  2. 解码:原样显示内容的时候必须解码,不然显示不到内容了。
  3. 过滤:把输入的一些不合法的东西都过滤掉,从而保证安全性。如移除用户上传的DOM属性,如onerror,移除用户上传的Style节点,iframe, script节点等。

通过一个例子讲解一下如何处理用户输入的数据。

实现原理如下:

  1. 存在一个parse函数,对输入的数据进行处理,返回处理之后的数据
  2. 对输入的数据(如DOM节点)进行解码(使用第三方库 he.js)
  3. 过滤掉一些元素有危害的元素节点与属性节点。如script标签,onerror事件等。(使用第三方库HTMLParser.js)
<script src='/javascripts/htmlparse.js'></script>
<script src='/javascripts/he.js'></script>
// 第三方库资源在文章底部给出 // parse函数实现如下 function parse (str) {
// str假如为某个DOM字符串
// 1. result为处理之后的DOM节点
let result = ''
// 2. 解码
let decode = he.unescape(str, {
strict: true
})
HTMLParser(decode, {
start (tag, attrs, unary) {
// 3. 过滤常见危险的标签
if (tag === 'script' || tag === 'img' || tag === 'link' || tag === 'style' || tag === 'iframe' || tag === 'frame') return
result += `<${tag}`
for (let i = 0; i < attrs.length; i++) {
let name = (attrs[i].name).toLowerCase()
let value = attrs[i].escaped
// 3. 过滤掉危险的style属性和js事件
if (name === 'style' || name === 'href' || name === 'src' || ~name.indexOf('on')) continue
result += ` ${name}=${value}`
}
result += `${unary ? ' /' : ''} >`
},
chars (text) {
result += text
},
comment (text) {
result += `<!-- ${text} -->`
},
end (tag) {
result += `</${tag}>`
}
})
return result
}
因此,有了以上的parse函数之后,就可以避免大部分的xss攻击了。 test.addEventListener('click', function () {
// ... 省略部分代码
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if ((xhr.status >= 200 && xhr.status <) || xhr.status === 304) {
// 3. 客户端解析JSON,并执行
// test按钮的点击事件中唯一的变化就是使用parse对服务端返回的数据进行了解码和过滤的处理。
var str = parse(JSON.parse(xhr.responseText).test)
// 通过parse解析之后返回的数据就是安全的DOM字符串
var node = `${str}`
document.body.insertAdjacentHTML('beforeend', node)
}
}
}
// ... 省略部分代码
}, false)

那么,栗子说完了。

稍微总结一下

  1. 一旦在DOM解析过程成出现不在预期内的改变(JS代码执行或样式大量变化时),就可能发生XSS攻击
  2. XSS分为反射型XSS,存储型XSS和DOM XSS
  3. 反射型XSS是在将XSS代码放在URL中,将参数提交到服务器。服务器解析后响应,在响应结果中存在XSS代码,最终通过浏览器解析执行。
  4. 存储型XSS是将XSS代码存储到服务端(数据库、内存、文件系统等),在下次请求同一个页面时就不需要带上XSS代码了,而是从服务器读取。
  5. DOM XSS的发生主要是在JS中使用eval造成的,所以应当避免使用eval语句。
  6. XSS危害有盗取用户cookie,通过JS或CSS改变样式,DDos造成正常用户无法得到服务器响应。
  7. XSS代码的预防主要通过对数据解码,再过滤掉危险标签、属性和事件等。

参考资源

  1. 《WEB前端黑客技术揭秘》
  2. 浅谈XSS攻击的那些事(附常用绕过姿势)
  3. XSS实战:我是如何拿下你的百度账号
  4. HTMLParser
  5. he
  6. Web安全-XSS

前端安全之XSS的更多相关文章

  1. 前端安全(XSS、CSRF防御)

    一.网络安全          OWASP:开放式Web应用程序安全项目(OWASP,Open Web Application Security Project)        OWASP是一个开源的 ...

  2. 前端安全之XSS攻击

    XSS(cross-site scripting跨域脚本攻击)攻击是最常见的Web攻击,其重点是“跨域”和“客户端执行”.有人将XSS攻击分为三种,分别是: 1. Reflected XSS(基于反射 ...

  3. 前端Hack之XSS攻击个人学习笔记

    简单概述 **        此篇系本人两周来学习XSS的一份个人总结,实质上应该是一份笔记,方便自己日后重新回来复习,文中涉及到的文章我都会在末尾尽可能地添加上,此次总结是我在学习过程中所写,如有任 ...

  4. 前端之困 · XSS CookBook

    方法论 发掘漏洞的时间要具体到是检测什么目标了,找 Google 的,和找腾讯的时间肯定不会一样. 至于是如何发现的,不同类型的 XSS 漏洞,可能不尽相同. 反射型 以及一些 DOM 型,一般建议是 ...

  5. 转:前端安全之XSS攻击

    前端安全 原文链接:https://www.freebuf.com/articles/web/185654.html 随着互联网的高速发展,信息安全问题已经成为企业最为关注的焦点之一,而前端又是引发企 ...

  6. 前端安全之XSS和csrf攻击

    1.Csrf攻击概念: csrf攻击(Cross-site request forgery):跨站请求伪造; 2.Csrf攻击原理: 用户是网站A的注册用户,且登录进去,于是网站A就给用户下发cook ...

  7. 前端安全之 XSS攻击

    参看: XSS的原理分析与解剖 前端安全 -- XSS攻击 web大前端开发中一些常见的安全性问题 1.前言 XSS 是面试时,hr提出来给我的,然后大体的浏览一遍,今天才查阅资料大体了解了它. XS ...

  8. [前端web安全]XSS漏洞基础入门

    前言 XSS漏洞 Xss(Cross-Site Scripting)意为跨站脚本攻击,为了不和层叠样式表(Cascading Style Sheets,CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS ...

  9. 前端 跨站脚本(XSS)攻击的一些问题,解决<script>alert('gansir')</script>

    问题1:跨站脚本(XSS)的一些问题,主要漏洞证据: <script>alert('gansir')</script>,对于这个问题怎么解决? (测试应当考虑的前端基础攻击问题 ...

随机推荐

  1. [转]extern "C"的作用

    extern "C"的主要作用就是为了能够正确实现C++代码调用其它C语言代码. 加上extern “C”后,会指示编译器将这部分代码按C语言进行编译,而不是C++的.这是因为C+ ...

  2. rsync远程同步的基本配置与使用

    rsync是一个开源的快速备份工具,可以在不同主机之间镜像同步整个目录树,支持增量备份,保持链接和权限,且采用优化的同步算法,传输前执行压缩,因此非常适用于异地备份,镜像服务器等应用. rsync的官 ...

  3. switch选择结构

    switch( 表达式 )//表达式可以使用byte,short,int,char { case 值1: 逻辑语句: break;//跳出switch语句 case 值2: 逻辑语句; break; ...

  4. Instruments模板介绍(更新中...)

    第一章.Instruments(仪器)快速入门 Instruments可以用来收集关于一个或者多个系统进程的性能和行为的数据,并跟踪睡着时间产生的数据.它提供了好几个分析模板: Blank 任何类型都 ...

  5. [java大数据面试] 2018年4月百度面试经过+三面算法题:给定一个数组,求和为定值的所有组合.

    给定一个数组,求和为定值的所有组合, 这道算法题在leetcode应该算是中等偏下难度, 对三到五年工作经验主要做业务开发的同学来说, 一般较难的也就是这种程度了. 简述经过: 不算hr面,总计四面, ...

  6. python之面向对象进阶

    接口类 抽象类 钻石继承 多态 鸭子类型 接口类 接口类 继承有两种用途: 一:继承基类的方法,并且做出自己的改变或者扩展(代码重用) 二:声明某个子类兼容于某基类,定义一个接口类Interface, ...

  7. python MD5加密方法

    import hashlibhash = hashlib.md5()hash.update('admin')print hash.hexdigest()

  8. XGBOOST应用及调参示例

    该示例所用的数据可从该链接下载,提取码为3y90,数据说明可参考该网页.该示例的“模型调参”这一部分引用了这篇博客的步骤. 数据前处理 导入数据 import pandas as pd import ...

  9. ucml选项卡

    当业务视图组件VC并排摆放时就会形成选项卡,本章介绍选项卡有关的操作函数和事件. 页面中有三个对象:TabStrip,Panel和Tab,TabStrip含Panel对象和Tab对象.业务单元BPO没 ...

  10. 在 Server 2008 企业版下, 安装 IIS 7 后,勾选好 请求筛选模块了。安装完毕后,"请求筛选"却不显示!

    下载并安装 Administration Pack 到你的Windows Server 2008 上.可以通过下面的链接来下载Administration Pack. https://www.iis. ...