Web安全 - CSRF 攻击

  • 作者:KK

  • 发表日期:2018.8.9


前提认知

你可能不知道,在火狐和Chrome浏览器里,A网站的图片和script标签src或者clinkc的href引用的样式,如果是引用了B网站的图片、脚本和样式,那么这个引用当然需要发个请求过去获取内容咯,然而这个请求是会附带B网站的 Cookie!

而另外,A网站的 form 表单同步提交到B网站的地址时也会带上B网站的 Cookie。


CSRF 攻击原理

用户登录了B网站,浏览器就有了登录相关的 Cookie,只要有这些 Cookie 去请求B网站那些需要登录才能查看的页面和操作都是合法的嘛。

而攻击者就在A网站加入了类似<img src="http://b.com/pay?money=1688&reciver=指定收款账户"/>或者src="http://b.com/logout.do"这样的图片地址,然后通过各种方式诱导用户在登录了B网站的情况下去访问A网站的页面加载这张看不见的图片,其实A网站一般是被攻击者入侵了的,或者攻击者通过渗透技术把代码值入进去的(比如XSS攻击),又或者本身就是攻击者自己做出来的钓鱼网站。

于是用户访问了A网站,A网站的图片地址引发浏览器加载,一旦加载又带上了B网站的 Cookie,就会执行相关的处理(就像示例的 src 地址那样的支付操作)。

这就是跨站脚本攻击(Cross-site request forgery)。


解决办法

  1. 作为B网站,我们往往应该将一些操作性的请求设定仅限于POSTPUTDELETE,任何GET的请求基本上就是只读的操作,像上面 src 为支付处理的例子,正常的程序员都会用POST来设计。

    可是还不能根治,因为A网站可以做一个action="POST"的 form 表单然后诱导用户去输入提交,只是困难了点儿。

  2. 增加页面 token,就是B网站进行支付什么的 POST 操作时都要在 POST 参数里附带一个 token 才可以处理。这个可能有些同学难以理解怎么做,其实就是B网站输出页面之前,生成一个对应的页面 token 通过 Cookie 传给前端(比如支付页面),前端要操作时也把这个 token 放在POST参数里向服务端发送回去,服务端就允许操作了。

可是A网站并不会有这个token,所以A站那边的用户点击欺骗性的 form 表单提交时,是不会带上这个页面 token 的。虽然A网站向B网站发起请求时会带上B网站的 Cookie 并且里面有页面 token,可是A网站没有办法将这个 Cookie 里的 token 加到 POST 参数里,所以是没问题的,其实A网站也没有任何通过代码的方式来获得B网站的 Cookie 值,只是利用了请求会带上B网站的 Cookie 这个特性来让用户执行他想要的操作而已。


注意

如果网站内还有 XSS漏洞,那么就算做好了以上所述的 CSRF 攻击防御都没用,因为攻击者可以走 XSS 漏洞向B网站注入恶意脚本,然后引导用户去B网站自己的页面触发他的脚本来操纵用户,这时候根本就是在B网站的页面下请求B网站本身,比 CSRF 攻击还要方便!所以 XSS 和 CSRF 两种攻击漏洞都要解决掉!