随着各浏览器安全功能的提高,前端防御面临的问题也没有之前那么复杂,但浏览器的防御措施并不能百分百的保证网站的安全。浏览器的XSS Auditor,使得反射型xss几乎被废;CSP(Content-Security-Policy)、X-XSS-Protection可以禁止不可信源的脚本执行!无疑,这对xss攻击是一记重拳。但是道高一尺,魔高一丈,尤其是在安全界,永远应该记住的一句箴言就是“只有相对的安全,没有绝对的安全”。本文重点介绍现代浏览器的安全特性以及浏览器依然不能防御的攻击手段。
XSS
XSS攻击:跨站脚本攻击(Cross Site Scripting),为不和 CSS混淆,故将跨站脚本攻击缩写为XSS。
为什么叫跨站脚本?简单来说,就是在一个网站上运行了该网站之外的js脚本(当然,开发者自已引用的可信源的js不算,比如使用了cdn的 jQuery )。
一个经典的例子
假设有一个搜索页面,关键字以Get方法传递。假设,搜索页面在输出结果时会无过滤的将用户的关键字回显到网页上,大致逻辑如下:
//xss.php
php
if(isset($_REQUEST["wd"]))
$wd=$_REQUEST["wd"];
if($wd){
echo "关键字'$wd'搜索的结果如下:"
}
...
?>
然后搜索请求的链接是:
http://localhost/test/haker/xss.php?wd=alert("xss")
或者为了隐蔽编一下码:
http://localhost/test/haker/xss.php?wd=ddd%3Cscript%3Ealert(%22%22)%3C/script%3E
在es6下,你甚者可以用unicode码点。
如果是在几年前,你的浏览器大致都会弹出这样一个窗口:

然而,现在不行了,在chrome和safari下,如果发现响应中包含请求参数中相同的代码字符串,它们就会拒绝执行这些代码,你会收到如下的错误提示:
The XSS Auditor refused to execute a script in 'http://localhost/test/haker/xss.php?wd=ddd%3Cscript%3Ealert(%22xss%22)%3C/script%3E' because its source code was found within the request. The auditor was enabled as the server sent neither an 'X-XSS-Protection' nor 'Content-Security-Policy' header.
XSS Auditor
xss auditor是Chrome 和 Safari中内建的一个防御xss攻击的功能模块,相当于一个审计器,有预设规则,主要功能就是针对上述这种情况。此功能默认是开启的,当然也可以关闭,需要在response header中显式指定:
//关闭 xss auditor
X-XSS-Protection: 0
当然,更强大的是,触发后还可以将详情上报,便于分析跟踪:
X-XSS-Protection: 1; report=http://example.com/your_report_URI
也可以使用block模式:一旦触发,当前页面就会终止,并同时展示一个空白页面给用户:
X-XSS-Protection: 1; mode=block
如果将请求换成post,xss auditor还会被触发吗?答案是:可以!
XSS Auditor的缺点
我们将后台逻辑改一下,给每个">"后加一个分号。
php
if(isset($_REQUEST["wd"]))
$wd=str_replace(">",">;",$_REQUEST["wd"]);
if($wd){
echo "关键字'$wd'搜索的结果如下:"
}
?>
然后依然是之前的链接,刷新:

成功了,当然本例只是一个说明,通常情况下,我们都会对用户提交的数据进行一些处理,如果这些处理导致和提交的内容不一样了,但是仍然可以执行,比如像本例一样。那么xss auditor 就无能为力了。不过xss auditor本身的智能度也挺高,像字符编码,大小写变化这种变化依然躲不过xss auditor。
存储型xss
比如网站有个留言板功能,但后台未对用户输入进行过滤,攻击者可以在留言编辑框中输入:
$("form").submit()
...
在b页面中,制造一个表单,然后直接触发提交,依然可以!
CSRF攻击防御
随机值法
后台对每一次请求都生成一个随机值,保存在session中,然后再将该值发送给页面,可以在cookie中,也可以在一个隐藏的表单中(大多数后台框架都是这么做的,如php的symfony、laraval),甚至也可以是在验证码中。下面以表单为例来说明:
然后提交时,服务端再对比hash值是不是和session中一样。 攻击者网站时无法预估这个hash的。但是请注意,在上面所述的攻击场景中,把hash存在cookie中时不行的。
检测refer
后台在进行删除操作之前先判断refer,如果不是本域的请求,则直接拒绝,这种做法很有效。但是,想想这样一个场景:如果博客允许评论里面插图,攻击者完全可以将 img插入到原网站中,这样refer还是在当下域名,博客依然会被删除。所有可能引入链接的html标签都是不可信的,如script、link,后台过滤策略一定要考虑到。
总结
其实可以看到,上面的攻击虽说现场是在前端,但是本质还是服务端验证不足、过滤不全导致。对于前端来说,防御所做的事有限,但是站在攻击者角度来讲,又必需精通前端。今天只是web渗透的皮毛,如果大家有兴趣,可以在评论中留言,以后也可以多分享一些服务器渗透、操作系统安全方面的,当然根据期待度以及我的时间而定。
最后: 刚开博客,求关注、求赞、求评论、求打赏!