其实从逻辑上讲,XSS和其他的漏洞诸如SQL注入、文件上传漏洞有很类似的地方:它们都可以通过一些特定的手段,将攻击的代码成功的传送到我们想要攻击的地方。那么有两个关键的环节:
1.代码的注入,即通过什么办法把攻击代码“送”到目的地。
2.代码本身的内容,直接决定着代码进行什么样的攻击,达到什么样的目的,决定着攻击的“威力”。
XSS就是一段由Javascript编写的攻击代码,这个代码能够实现多种攻击功能,对应着XSS的危害,这里我们先不说代码本身的问题,那么XSS漏洞又是什么,其实就是指的我们可以通过一些办法把代码“送”到攻击地点,那么有几种办法(类型)呢?漏洞又是如何产生的呢?总结一句话,XSS漏洞就是通过一些手段在网页嵌入客户端脚本代码,最终在浏览器上执行的客户端攻击。
XSS漏洞分为:反射型、DOM型和存储型。
(1)反射型是通过在URL中做手脚来攻击的,比如我们在一段URL中直接插入JS攻击代码,如果前端和后端都没有识别出URL中有XSS代码,这段代码的“旅程”就是:1.随着URL被提交 2.服务器接收后直接返回带有该代码的数据 3.浏览器解析执行
为什么叫反射型?只是因为服务器相当于进行了一个“吞吐”的过程,类似于反射的过程,但是有一点很关键:代码必须经过浏览器“吞吐”这一次之后才会出现在返回给浏览器的数据中,这样代码才能被执行,否则代码还是在URL中式没办法被解析执行的。
(2)DOM型和反射型不同,它不需要与服务器进行交互,没有经过服务器“吞吐”的过程,因为它的代码利用的是HTML中DOM的一些方法来输出的,比如document.write方法、innerHTML属性等,直接把代码导出到DOM元素中执行的,它的触发是在浏览器解析DOM的时候出现的。
(3)存储型,存储型就厉害了,它是把代码直接传到服务器中,那么上传代码的那个网页就会含有这段代码,它的攻击仍然发生在客户端,每次点击页面服务器就会向客户端发送XSS代码让浏览器执行。这时候服务器的被感染页面就成了攻击源。
那么这三种攻击是怎么触发的?
反射型可以通过对URL的参数进行过滤和检查来防御,对预定义字符进行检查,利用转义函数、过滤函数等对URL参数进行检查,对输出进行实体编码,严格控制输出,从输入和输出两方面把关。DOM型可以过滤关键字,对敏感关键字进行过滤,并且innerHTML=encodeHTML([输出]);存储型根据场景的不同,进行对应的输入检查和过滤,如留言板,对留言内容进行敏感字符、关键字的检查和过滤,对输出的内容进行实体编码。
总结一下三种XSS的防御思路是相通的,都是把握好输入检查和输出检查两个方面,只不过应用的具体场景不同,可以把XSS防御的思路总结为:
1.对输入进行严格检查,过滤敏感字符和关键字。
2.使用白名单,提高防护等级,非白名单直接忽略。
3.对输出进行实体编码。
4.使用HTTPonly组织客户端访问cookie,保护cookie不被XSS窃取。