一、什么是CSRF漏洞?
CSRF跨站请求伪造,主要表现为:攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作,例如以你的名义发送邮件或消息,盗取你的账号,添加系统管理员,甚至于购买商品、虚拟货币转账等。
CSRF现状:CSRF这种攻击方式在2000年已经被国外的安全人员提出,但在国内,直到06年才开始被关注,08年,国内外的多个大型社区和交互网站分别爆出CSRF漏洞,如:NYTimes.com、Metafilter(一个大型的BLOG网站),YouTube和百度。而现在,互联网上的许多站点仍对此毫无防备,以至于安全业界称CSRF为“沉睡的巨人”。
二、CSRF漏洞是如何攻击的?
(1)受害者登录AA.com,并保留了登录凭证(Cookie)
(2)攻击者引诱受害者访问了BB.com
(3)BB.com 向 AA.com 发送了一个请求:a.com/act=xx。浏览器会默认携带AA.com的Cookie
(4)AA.com接收到请求后,对请求进行验证,并确认是受害者的凭证,误以为是受害者自己发送的请求
(5)AA.com以受害者的名义执行了act=xx
(6)攻击完成,攻击者在受害者不知情的情况下,冒充受害者,让AA.com执行了自己定义的操作
三、几种常见的CSRF:
(1)GET类型的CSRF
这类攻击非常简单,只需要一个HTTP请求:
<img src=””>
(2)POST类型的CSRF
这种类型的 CSRF 利用起来通常使用的是一个自动提交的表单,如:
<form action=" method=POST>
<input type="hidden" name="account" value="airing" />
<input type="hidden" name="amount" value="10000" />
<input type="hidden" name="for" value="hacker" /></form>
<script> document.forms[0].submit(); </script>
访问该页面后,表单会自动提交,相当于模拟用户完成了一次 POST 操作。可见这种类型的 CSRF 与第一种一样,都是模拟请求,所以后端接口也不能将安全寄托在仅允许 POST 请求上。
(3)链接类型的 CSRF
链接类型的CSRF并不常见,比起其他两种用户打开页面就中招的情况,这种类型需要用户点击链接才会触发,但本质上与前两种一样。这种类型通常是在论坛发布的图片中嵌入恶意链接,或者以广告的形式诱导用户中招,攻击者通常会以比较夸张的词语诱骗用户点击,例如:
<a href=" taget="_blank"> <a/>
由于之前用户登录了信任的网站A,并且保存登录状态,只要用户主动访问这个页面,则表示攻击成功。
四、如何防御CSRF?
(1)验证HTTP Referer字段
Referer是HTTP头中的一个字段,记录了 HTTP 请求的来源地址。这种方法的显而易见的好处就是简单易行,网站的普通开发人员不需要操心 CSRF 的漏洞,只需要在最后给所有安全敏感的请求统一增加一个拦截器来检查Referer 的值就可以。特别是对于当前现有的系统,不需要改变系统的任何已有代码和逻辑,没有风险,非常便捷。
然而,这种方法并非万无一失。Referer 的值是由浏览器提供的,虽然 HTTP 协议上有明确的要求,但是每个浏览器对于 Referer 的具体实现可能有差别,并不能保证浏览器自身没有安全漏洞。
(2)请求中添加token并验证
token就是服务端返回给客户端类似sessionid那样一长串的类值(长是为了防暴力猜解)。 CSRF依赖于浏览器访问链接时自动对应网站的cookie带上,token不放cookie(一般form表单加个hidden属性的input标签来存放) CSRF就没法获取token,这样我们就可以通过检测发送过来的数据包中是否有正确的token值来决定是否响应请求。
这种方法要比检查 Referer 要安全一些,token 可以在用户登陆后产生并放于 session 之中,然后在每次请求时把 token 从 session 中拿出,与请求中的 token 进行比对,但这种方法的难点在于如何把 token 以参数的形式加入请求。对于 GET 请求,token 将附在请求地址之后,这样 URL 就变成 。 而对于 POST 请求来说,要在 form 的最后加上 ,这样就可以把 token 以参数的形式加入请求了。另外还有一个问题就是怎么保障token本身的存储安全,不要被黑客截获。