[点晴永久免费OA]跨站脚本攻击XSS案例及其解决方案
当前位置:点晴教程→点晴OA办公管理信息系统
→『 经验分享&问题答疑 』
跨站脚本攻击XSS目录 跨站脚本攻击(Cross Site Script为了区别于CSS简称为XSS)指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意用户的特殊目的。 案例一:留言板的XSS攻击我们有个页面用于允许用户发表留言,然后在页面底部显示留言列表
addElement()方法用于添加新的留言,而renderComments()方法用于展留言列表,网页看起来是这样的 XSS 因为我们完全信任了用户输入,但有些别有用心的用户会像这样的输入 这样无论是谁访问这个页面的时候控制台都会输出“Hey you are a fool fish!”,如果这只是个恶意的小玩笑,有些人做的事情就不可爱了,有些用户会利用这个漏洞窃取用户信息、诱骗人打开恶意网站或者下载恶意程序等,看个最简单的例子
利用xss窃取用户名密码当然这个示例很简单,几乎攻击不到任何网站,仅仅看看其原理。我们知道很多登陆界面都有记住用户名、密码的功能方便用户下次登录,有些网站是直接用明文记录用户名、密码,恶意用户注册账户登录后使用简单工具查看cookie结构名称后,如果网站有xss漏洞,那么简单的利用jsonp就可以获取其它用户的用户名、密码了。 恶意用户会这么输入: 我们看看http://test.com/hack.js里藏了什么:
几句简单的javascript,获取cookie中的用户名密码,利用jsonp把向 http://test.com/index.php 发送了一个get请求,来看一下http://test.com/index.php中的内容:
这样恶意用户就把访问留言板的用户的信息窃取了。 案例二:输入框的XSS攻击有一个登录页面: 如果我有用户abc,密码123,输入用户名abc,密码567,提示密码错误,但是为了避免用户再次输入用户名,将输入的用户名在页面上保留。此时的html页面是这样的,按f12查看: 好,场景描述完毕,xss跨站脚本开始了: 1、如果我直接在用户名这里输入<script>alert("1")</script>,然后输入一个错误的密码,并没有执行script代码,因为返回的html页面是这样的: 上图中那样的script代码是不会执行的,因为在input的value中,只有独立的形如下的script代码才会执行。 所以要想实现script代码的执行,就需要进行拼接,将script代码排到input标签外。 怎么实现呢? 说白了就是自己拼接,将input标签进行闭合,然后将script代码缀在后边。 通过用户名的输入,将input拼接成如下,即可实现script代码的执行: <input name="userName" class="textcss" id="userName" type="text" value="abc"/><script>alert("1")</script>"/> 为什么会执行? 可以将拼接后的input拆分看一下,就很明白了 <input name="userName" class="textcss" id="userName" type="text" value="abc"/> <script>alert("1")</script> "/> 因为input已经闭合了,所以script代码会执行,至于拼接后的html文件是有语法错误的问题(因为最后剩下一个"/>,这个html是有错误的,但是不影响页面展示和script代码执行)就可以忽略了。 因此,只需要在用户名那里输入: abc"/><script>alert("1")</script> 然后输入一个错误的密码,点击登录,就会执行script代码,弹出弹框。
怎么预防服务端可以干的事1. HttpOnly 其实就是现在HTTP协议(HTTPS也是可以的)才能读取cookies,JavaScript是读取不到cookies的。支持浏览器是IE6+、Firefox2+、Google、Safari4+。 JavaEE给Cookie添加HttpOnly的代码:
PS:对于HTTPS,还是可以设置Secure字段,对Cookie进行安全加密。 这是本质上不是预防XSS,而是在被攻破时候不允许JS读取Cookie。 2.处理富文本 有些数据因为使用场景问题,并不能直接在服务端进行转义存储。不过富文本数据语义是完整的HTML代码,在输出时也不会拼凑到某个标签的属性中,所以可以当特殊情况特殊处理。处理的过程是在服务端配置富文本标签和属性的白名单,不允许出现其他标签或属性(例如script、iframe、form等),即”XSS Filter“。然后在存储之前进行过滤(过滤原理没有去探明)。 Java有个开源项目Anti-Samy是非常好的XSS Filter:
PS:当然也可以在前端显示前过滤,但是我觉得,让前端人员少做东西好,并且服务端只需要转一次。
客户端可以干的事1. 输入检查 输入检查的逻辑,必须放在服务器端代码中实现(因为用JavaScript做输入检查,很容易被攻击者绕过)。目前Web开发的普遍做法,是同时在客户端JavaScript中和服务器代码中实现相同的输入检查。客户端JavaScript的输入检查,可以阻挡大部分误操作的正常用户,从而节约服务资源。 PS:简单说,就是输入检查,服务端和客户端都要做。 另外攻击者可能输入XSS的地方,例如: 1.页面中所有的input框 2.window.location(href、hash等) 3.window.name 4.document.referrer 5.document.cookie 6.localstorage 7.XMLHttpRequest返回的数据 PS:当然不止这些 2. 输出检查 一般就是在变量输出到HTML页面时,使用编码或转义的方式来防御XSS攻击。XSS的本质就是“HTML注入”,用户的数据被当成了HTML代码一部分来执行,从而混淆了原本的语义,产生了新的语义。 触发XSS的地方 1.document.write 2.xxx.innerHTML= 3.xxx.outerHTML= 4.innerHTML.replace 5.document.attachEvent 6.window.attachEvent 7.document.location.replace 8.document.location.assign PS:如果使用jquery,就是那些append、html、before、after等,其实就是拼接变量到HTML页面时产生。大部分的MVC框架在模板(view层)会自动处理XSS问题,例如AngularJS。 用什么编码转义 主要有HTMLEncode和JavaScriptEncode这两个,客户端和服务端都能做。但是让后端去做,我感觉是不大靠谱的,因为数据的使用场景可能有几种,可以在标签、属性、或脚本里(甚至其他终端使用),单单以一种方式去encode是很极限的。 1.HTMLEncode,就是将字符转换成HTMLEntities,一般会转(&、<、>、"、''、/)这6个字符。 2.JavaScriptEncode,是使用”\“对特殊字符进行转义。 PS:我在《HtmlEncode和JavaScriptEncode(预防XSS)》一文总结了比较完整的HTMLEncode和JavaScriptEncode两个前端函数的写法,以及一点示例。 哪些地方需要编转义 1.在HTML标签、属性中输出——用HTMLEncode 2.在script标签中输出——用JavaScriptEncode 3.在事件中输出——用JavaScriptEncode <a href="#" οnclick="funcA(''$var'')">test</a> 4.在CSS中输出 用类似JavaScriptEncode的方式。将除了字母、数字外的所有字符都编码成十六进制形式”\uHH“。 5.在地址中输出 一般如果变量是整个URL,则先检查变量是否以“http”开头(不是则帮忙添加http),保证不会出现伪协议类的XSS攻击。然后再对变量进行URLEncode。 PS:URLEncode会将字符转换成”%HH“形式。 总结 前端开发人员要注意在正确的地方使用正确的编码方式,有时为了防御XSS,在一个地方我们需要联合HTMLEncode、JavaScriptEncode进行编码,甚至是叠加,并不是固定一种方式编码(又是具体情况具体分析)。 一般存储型XSS风险高于反射型XSS。反射型XSS一般要求攻击者诱使用户点击一个包含XSS代码的URL链接;而存储型只需要用户查看一个正常的URL链接,当用户打开页面时,XSS Payload就会被执行。这样漏洞极其隐蔽,且埋伏在用户的正常业务中,风险很高。(引自白帽子讲Web安全原文) 该文章在 2020/4/8 16:08:35 编辑过 |
关键字查询
相关文章
正在查询... |