javascript
css
html
前端
举一个小例子java
使用express起一个web服务器,而后设置一下请求接口。经过ajax的GET请求将参数发往服务器,服务器解析成json后响应。将返回的数据解析后显示到页面上。(没有对返回的数据进行解码和过滤等操做。)node
1 html 2 <textarea name="txt" id="txt" cols="80" rows="10"> 3 <button type="button" id="test">测试</button> 4 5 js 6 var test = document.querySelector('#test') 7 test.addEventListener('click', function () { 8 var url = `/test?test=${txt.value}` // 1. 发送一个GET请求 9 var xhr = new XMLHttpRequest() 10 xhr.onreadystatechange = function () { 11 if (xhr.readyState === 4) { 12 if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) { 13 // 3. 客户端解析JSON,并执行 14 var str = JSON.parse(xhr.responseText).test 15 var node = `${str}` 16 document.body.insertAdjacentHTML('beforeend', node) 17 } else { 18 console.log('error', xhr.responseText) 19 } 20 } 21 } 22 xhr.open('GET', url, true) 23 xhr.send(null) 24 }, false) 25 26 express 27 var express = require('express'); 28 var router = express.Router(); 29 30 router.get('/test', function (req, res, next) { 31 // 2. 服务端解析成JSON后响应 32 res.json({ 33 test: req.query.test 34 }) 35 })
如今咱们经过给textarea添加一段有攻击目的的img标签,git
<img src="null" onerror='alert(document.cookie)' />
实际的页面时这样的。github
ok如今,咱们点击<测试>按钮,一个XSS攻击就发生了。下面图片中是获取了本地的部分cookie信息web
实际上,咱们只是模拟攻击,经过alert获取到了我的的cookie信息。可是若是是黑客的话,他们会注入一段第三方的js代码,而后将获取到的cookie信息存到他们的服务器上。这样的话黑客们就有机会拿到咱们的身份认证作一些违法的事情了。ajax
以上,存在的一些问题,主要在于没有对用户输入的信息进行过滤,同时没有剔除掉DOM节点中存在的一些有危害的事件和一些有危害的DOM节点。
1 test.addEventListener('click', function () { 2 var node = window.eval(txt.value) 3 window.alert(node) 4 }, false) 5 6 txt中的代码以下 7 <img src='null' onerror='alert(123)' />
以上经过eval语句就形成了XSS攻击。
使用js或css破环页面正常的结构与样式
流量劫持(经过访问某段具备window.location.href定位到其余页面)
Dos攻击:利用合理的客户端请求来占用过多的服务器资源,从而使合法的用户没法获得服务器响应
利用iframe、frame、XMLHttpRequest或上述Flash等方式,以(被攻击)用户的身份执行一些管理动做,或执行一些通常的如发微博、加好友、发私信等操做。
利用可被攻击的域受到其余域信任的特色,以受信任来源的身份请求一些平时不容许的操做,如进行不当的投票活动。
没有过滤危险的属性节点。如事件,style,src,href等
没有对cookie设置httpOnly
若是将以上三点都在渲染过程当中过滤,那么出现的XSS攻击的改了也就小不少。
解决方法以下
2.解码:原样显示内容的时候必须解码,否则显示不到内容了。
3.过滤:把输入的一些不合法的东西都过滤掉,从而保证安全性。如移除用户上传的DOM属性,如onerror,移除用户上传的Style节点,iframe, script节点等。
经过一个例子讲解一下如何处理用户输入的数据。
存在一个parse函数,对输入的数据进行处理,返回处理以后的数据
对输入的数据(如DOM节点)进行解码(使用第三方库 he.js)
过滤掉一些元素有危害的元素节点与属性节点。如script标签,onerror事件等。(使用第三方库HTMLParser.js)
1 <script src='/javascripts/htmlparse.js'></script> 2 <script src='/javascripts/he.js'></script> 3 // 第三方库资源在文章底部给出 4 5 // parse函数实现以下 6 7 function parse (str) { 8 // str假如为某个DOM字符串 9 // 1. result为处理以后的DOM节点 10 let result = '' 11 // 2. 解码 12 let decode = he.unescape(str, { 13 strict: true 14 }) 15 HTMLParser(decode, { 16 start (tag, attrs, unary) { 17 // 3. 过滤常见危险的标签 18 if (tag === 'script' || tag === 'img' || tag === 'link' || tag === 'style' || tag === 'iframe' || tag === 'frame') return 19 result += `<${tag}` 20 for (let i = 0; i < attrs.length; i++) { 21 let name = (attrs[i].name).toLowerCase() 22 let value = attrs[i].escaped 23 // 3. 过滤掉危险的style属性和js事件 24 if (name === 'style' || name === 'href' || name === 'src' || ~name.indexOf('on')) continue 25 result += ` ${name}=${value}` 26 } 27 result += `${unary ? ' /' : ''} >` 28 }, 29 chars (text) { 30 result += text 31 }, 32 comment (text) { 33 result += `<!-- ${text} -->` 34 }, 35 end (tag) { 36 result += `</${tag}>` 37 } 38 }) 39 return result 40 }
所以,有了以上的parse函数以后,就能够避免大部分的xss攻击了。
1 test.addEventListener('click', function () { 2 // ... 省略部分代码 3 xhr.onreadystatechange = function () { 4 if (xhr.readyState === 4) { 5 if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) { 6 // 3. 客户端解析JSON,并执行 7 // test按钮的点击事件中惟一的变化就是使用parse对服务端返回的数据进行了解码和过滤的处理。 8 var str = parse(JSON.parse(xhr.responseText).test) 9 // 经过parse解析以后返回的数据就是安全的DOM字符串 10 var node = `${str}` 11 document.body.insertAdjacentHTML('beforeend', node) 12 } 13 } 14 } 15 // ... 省略部分代码 16 }, false)
那么,例子说完了
稍微总结一下
XSS分为反射型XSS,存储型XSS和DOM XSS
反射型XSS是在将XSS代码放在URL中,将参数提交到服务器。服务器解析后响应,在响应结果中存在XSS代码,最终经过浏览器解析执行。
存储型XSS是将XSS代码存储到服务端(数据库、内存、文件系统等),在下次请求同一个页面时就不须要带上XSS代码了,而是从服务器读取。
DOM XSS的发生主要是在JS中使用eval形成的,因此应当避免使用eval语句。
XSS危害有盗取用户cookie,经过JS或CSS改变样式,DDos形成正经常使用户没法获得服务器响应。
XSS代码的预防主要经过对数据解码,再过滤掉危险标签、属性和事件等。
参考资源