前端安全的XSS攻击

前者安全之XSS

转载请注明出处:unclekeith:
前者安全之XSS

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 < 300) || 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)' />

其实的页面时如此的。
图片 1
ok现在,我们点击<测试>按钮,一个XSS攻击就来了。下面图片中凡是得到了当地的一些cookie信息
图片 2
实则,我们只是学攻击,通过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 < 300) || 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