目前主流过滤XSS的三种技术
过滤
过滤,顾名思义,就是将提交上来的数据中的敏感词汇直接过滤掉。例如对"<script>"、"<a>"、"<img>"等标签进行过滤,有的是直接删除这类标签中的内容,有的是过滤掉之类标签中的on事件或是'javascript'等字符串,让他们达不到预期的DOM效果。
编码
像一些常见的字符,如"<"、">"等。对这些字符进行转换编码或者转义,让他们不直接出现在脚本中,从而使浏览器不会去执行这段脚本
限制
玩过XSS的朋友应该都知道,精心构造一个攻击链接往往需要较长的字符串。那我干脆就对提交上来的数据长度做一个限制,这样就能解决一个即使真的存在一个XSS漏洞,但由于数据长度的限制而导致这个漏洞无法真正被利用的情况。
常见绕过技术
1. 防过滤
有的网站会直接过滤"<script>"、"<a>"、"<img>"这些标签。在测试过程中,我们可以改变测试语句的大小写来绕过XSS规则.比如:
<script>alert("xss");</script>
可以转换为:
<ScRipt>ALeRt("XSS");</sCRipT>
对于只过滤一次“script”的情况我们还可以很巧合地把请求构造成这样:
<scr<script>ipt>alert("XSS")</scr<script>ipt>
对于完全过滤"script"、"javascript"等脚本相关的字符时,我们可以使用DOM Based XSS,例如:
<img src=1 οnerrοr=alert(1)>
编码类:编码类绕过主要有URL编码,unicode编码,HTML编码,CSS编码和非常冷门的js-fuck编码
1. URL编码
URL编码最常见的是在用GET/POST传输时,顺序是把字符改成%+ASCII两位十六进制(先把字符串转成ASCII编码,然后再转成十六进制)。js处理URL编码的时候有三个函数可以使用,分别是escape()函数、encodeURI()函数 、encodeURIComponent()函数,对应的解码函数分别是unescape()、decodeURI()、decodeURIComponent();
2. unicode编码
Unicode编码的字符以%u为前缀,后面是这个字符的十六进制unicode的码点。当有些站点的后端验证可以识别Unicode编码的字符时,就可以用这个方法绕过了。
3. HTML编码
HTML编码的存在就是让他在代码中和显示中分开, 避免错误。他的命名实体:构造是&加上希腊字母,字符编码:构造是&#加十进制、十六进制ASCII码或unicode字符编码,而且浏览器解析的时候会先把html编码解析再进行渲染。但是有个前提就是必须要在“值”里。
4. CSS编码
主要是利用css中的expression()表达式表达式中可以执行js脚本来达到攻击的目的,但是我刚刚测试了一下expression()表达式在IE7及以下是有效的,在IE8及以上就失效了,无法识别。这种方法目前应该是无法使用了。
5. Ascii编码
这种方式主要利用了js的eval()函数和String.fromCharCode()函数。eval()函数是一个神奇的函数,可以用来计算一个字符串,将字符串变为js的表达式或者可执行语句,String.fromCharCode()函数则是将一段Ascii码转化为字符串。配合起来就例如下面的这一句代码:
<script>eval(String.fromCharCode(97,108,101,114,116,40,47,120,115,115,47,41));</script>
其作用相当于
<script>alert(/xss/)</script>
2. 针对限制
既然限制了数据长度,那我们可以从外部引用一个自己写的js,而不是直接全部写在请求当中。比如先自己写一个内容为alert(1)的js文件,上传到自己的空间里,由于script允许从外部引入js脚本,所以我们加上这句
"><script src='xss.js'></script>
直接加载脚本,可以突破对数据长度的限制。
3. 更多...
这里引用了一下别人整理得比较全的资料
总结
上面就总结了一些常见的XSS防护方式和绕过方式。其实XSS的绕过方式远远不止这么一些,这里我推荐一篇github上的帖子,对XSS的防护也是总结的比较详细的:
对于攻击来说,无论如何就一句话,尽可能得让你的脚本能够被执行。
对于防护来说,该过滤的过滤,该转义的转义,尽量做到全面。
另外我们可以想一下XSS攻击是为了什么,无非是通过脚本访问本地存储的cookie和劫持流量实现恶意跳转。那么对于前者,我们可以使用HTTP-only(HTTP-only技术就是可以组织用户通过脚本来访问cookie,只允许通过HTTP协议来访问和传输,通常写在服务器发送给客户端的报文头中)来防护;对于后者,可以使用HTTPS安全协议。所以我们也可以不要局限于如何把XSS防护得一丝不漏,而在通过XSS要达到的目的上多下点功夫。
后记
我在测试XSS的时候发现Chrome的内核自带了一个XSS_AUDITOR的功能,这个功能基本是无法防护持续型(存储型)XSS的,但是却阻止了我全部的非持续型的XSS,所有非持续型XSS都无法绕过他的检测。所以想请教下大家非持续型XSS能不能绕过Chrome的这个功能的,该怎样绕过。