随着互联网的高速发展,信息安全问题已经成为企业最为关注的焦点之一,而前端又是引发企业安全问题的高危据点。在移动互联网时代,前端人员除了传统的 XSS、CSRF 等安全问题之外,又时常遭遇网络劫持、非法调用 Hybrid API 等新型安全问题。当然,浏览器自身也在不断在进化和发展,不断引入 CSP、Same-Site Cookies 等新技术来增强安全性,但是仍存在很多潜在的威胁,这需要前端技术人员不断进行“查漏补缺”。
最近在解决网站CSRF安全服务漏洞,看了好多文档,有一下理解和总结:
CSRF
是跨站请求伪造的缩写,也被称为XSRF
, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。
跟跨网站脚本(XSS)相比,XSS利用的是用户对指定网站的信任,CSRF利用的是网站对用户网页浏览器的信任。
因为CSRF攻击利用的是冲着浏览器分不清发起请求是不是真正的用户本人。,也就是说,简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。
一个典型的CSRF攻击有着如下的流程:
接下来有请小明出场~~
小明的悲惨遭遇
这一天,小明同学百无聊赖地刷着Gmail邮件。大部分都是没营养的通知、验证码、聊天记录之类。但有一封邮件引起了小明的注意:
甩卖比特币,一个只要998!!
聪明的小明当然知道这种肯定是骗子,但还是抱着好奇的态度点了进去(请勿模仿)。果然,这只是一个什么都没有的空白页面,小明失望的关闭了页面。一切似乎什么都没有发生......
在这平静的外表之下,黑客的攻击已然得手。小明的Gmail中,被偷偷设置了一个过滤规则,这个规则使得所有的邮件都会被自动转发到[email protected]。小明还在继续刷着邮件,殊不知他的邮件正在一封封地,如脱缰的野马一般地,持续不断地向着黑客的邮箱转发而去。
不久之后的一天,小明发现自己的域名已经被转让了。懵懂的小明以为是域名到期自己忘了续费,直到有一天,对方开出了 $650 的赎回价码,小明才开始觉得不太对劲。
小明仔细查了下域名的转让,对方是拥有自己的验证码的,而域名的验证码只存在于自己的邮箱里面。小明回想起那天奇怪的链接,打开后重新查看了“空白页”的源码:
这个页面只要打开,就会向Gmail发送一个post请求。请求中,执行了“Create Filter”命令,将所有的邮件,转发到“[email protected]”。
小明由于刚刚就登陆了Gmail,所以这个请求发送时,携带着小明的登录凭证(Cookie),Gmail的后台接收到请求,验证了确实有小明的登录凭证,于是成功给小明配置了过滤器。
黑客可以查看小明的所有邮件,包括邮件里的域名验证码等隐私信息。拿到验证码之后,黑客就可以要求域名服务商把域名重置给自己。
小明很快打开Gmail,找到了那条过滤器,将其删除。然而,已经泄露的邮件,已经被转让的域名,再也无法挽回了......
以上就是小明的悲惨遭遇。而“点开一个黑客的链接,所有邮件都被窃取”这种事情并不是杜撰的,此事件原型是2007年Gmail的CSRF漏洞:
https://www.davidairey.com/google-Gmail-security-hijack/
当然,目前此漏洞已被Gmail修复,请使用Gmail的同学不要慌张。
几种常见的攻击类型
GET类型的CSRF利用非常简单,只需要一个HTTP请求,一般会这样利用:
在受害者访问含有这个img的页面后,浏览器会自动向http://bank.example/withdraw?account=xiaoming&amount=10000&for=hacker
发出一次HTTP请求。bank.example就会收到包含受害者登录信息的一次跨域请求。
这种类型的CSRF利用起来通常使用的是一个自动提交的表单,如:
访问该页面后,表单会自动提交,相当于模拟用户完成了一次POST操作。
POST类型的攻击通常比GET要求更加严格一点,但仍并不复杂。任何个人网站、博客,被黑客上传页面的网站都有可能是发起攻击的来源,后端接口不能将安全寄托在仅允许POST上面。
链接类型的CSRF并不常见,比起其他两种用户打开页面就中招的情况,这种需要用户点击链接才会触发。这种类型通常是在论坛中发布的图片中嵌入恶意链接,或者以广告的形式诱导用户中招,攻击者通常会以比较夸张的词语诱骗用户点击,例如:
重磅消息!!
由于之前用户登录了信任的网站A,并且保存登录状态,只要用户主动访问上面的这个PHP页面,则表示攻击成功。
CSRF的特点
CSRF通常是跨域的,因为外域通常更容易被攻击者掌控。但是如果本域下有容易被利用的功能,比如可以发图和链接的论坛和评论区,攻击可以直接在本域下进行,而且这种攻击更加危险。
cookie
。![]()
标签:
cookie
,这样浏览器发出的这个请求就能得到响应执行。危险网站可以伪造一个表单并隐藏,并在自己网站的onload
事件中,触发这个表单的提交事件,就可以改GET攻击为POST攻击
我们要防范它,先要知道它的目标,然后设法保护这些目标。
我们要明白,仅仅靠发起CSRF攻击的话,黑客只能借助受害者的cookie
骗取服务器的信任,但是黑客并不能凭借拿到cookie
,也看不到 cookie
的内容。另外,对于服务器返回的结果,由于浏览器同源策略的限制,黑客也无法进行解析。
这就告诉我们,我们要保护的对象是那些可以直接产生数据改变的服务,而对于读取数据的服务,则不需要进行CSRF
的保护。
而保护的关键,是 在请求中放入黑客所不能伪造的信息
防范手段
这个方法的确可以防范一些CSRF
攻击,但是对于进阶攻击就无能为力了——POST
请求一样可以伪造。
所以这个方法不够安全。只能提高攻击的门槛。
方法:添加验证码来识别是不是用户主动去发起这个请求,由于一定强度的验证码机器无法识别,因此危险网站不能伪造一个完整的请求。
优点:简单粗暴,低成本,可靠,能防范99.99%的攻击者。
缺点:对用户不友好。
方法:在HTTP
请求头中有一个字段叫Referer
,它记录了请求的来源地址。 服务器需要做的是验证这个来源地址是否合法,如果是来自一些不受信任的网站,则拒绝响应。
优点:零成本,简单易实现。
缺点:由于这个方法严重依赖浏览器自身,因此安全性全看浏览器。
Referer
的具体实现可能有差别。Referer
可以被篡改。Referer
值会记录下用户的访问来源,有些用户认为这样会侵犯到他们自己的隐私权。因此有些用户可能会开启浏览器防止跟踪功能,不提供Referer
,从而导致正常用户请求被拒绝。
方法:使用token
来代替验证码验证。由于黑客并不能拿到和看到cookie
里的内容,所以无法伪造一个完整的请求。基本思路如下:
token
(比如把cookie
hash化生成),存在session
中,放在cookie
中或者以ajax
的形式交给前端。cookie
中的token
,放到请求url
里或者请求头中。token
,由于黑客无法得到或者伪造token
,所以能防范csrf
更进一步的加强手段(不需要session):
token
,然后以token
为密钥散列生成一段密文token
和密文都随cookie
交给前端token
都交给后端token
和密文进行正向散列验证,看token
能不能生成同样的密文token
也无法拿到密文。优点:
缺点:
hash
计算,增加性能上的成本cookie
臃肿:更加依赖网络的情况token
,这样黑客可以在自己的网站上得到这个 token
,并马上就可以发动CSRF攻击。(进一步加强法可以防范,或者验证链接是否是链到自己本站,是的就在后面添加 token
,如果是通向外网则不加cookie
和token
,当然这不在本文的讨论范围之内。4.对于POST请求,难以将token
附在请求中。(可以通过框架和库解决)
方法:这种方法也是使用token并进行验证,和上一种方法不同的是把它放到HTTP头中自定义的属性里。
优点:
缺点:
详细解决请参考链接:https://my.oschina.net/meituantech/blog/2243958