定义
CSRF: cross-site request forgery(跨站点申请伪造)
导致的起因
这要从Cookie的作用来讲起。咱们晓得HTTP申请是无状态的,然而在理论的web利用中,咱们须要申请是有状态的,比方咱们须要记住登录的状态,不必每一个申请都从新登录。想要实现这样的需要咱们就须要Cookie。
Cookie在服务器端通过Set-Cookie
来设置须要存储在Cookie的值,而后存储在客户端(浏览器)。之后在客户端发动的任何指向同一个domain的申请中,都会带上这些Cookie的信息。
那么问题就来了,这里只有是针对同一个domain的申请都会带上cookie,然而并不限度这些申请是从哪里发动的。
咱们来看看上面的场景:
至此,咱们应该对CSRF Token有了一个清晰的理解。
在Rails中怎么避免
在Rails中,避免这种攻打的办法,就是在任何非GET的申请中,都要验证一个authenticity token. 这个token对应到每一个session,每次生成session的时候就随机产生一个token,并存储在session中。当向服务器发送申请(非GET)的时候须要带上这个token。
那么问题是前端代码发送申请的时如何获取这个token呢?
在Rails中,如果你是应用form helper的话,在后端render的时候,会从session中去读取这个token并插入到form的hidden field中。如果你是通过FE JS 发送ajax申请的话,你须要从本站的layout的meta tag中去读区这个token。
所以对于在第三方站点(B站)上的申请来讲,它是得不到这个token的(如果他曾经能失去这个token,阐明他曾经有了session,也就没必要再通过B站来发申请了),所以这个申请在服务器端将会无奈通过验证。
补充信息:
Rails在比拟token是否统一的时候,有一个对request.base_url
和 request.origin
的比拟。
这里base_url指的是这次申请的domain地址,origin指的是这个申请是从哪里来的。
请看上面的例子:
假如咱们在站点Bhttps://websiteb.com
触发了一个到站点Ahttps://websitea.com
的申请:POST https://websitea.com/path
那么此时在A的server:request.base_url
是 https://websitea.com
request.origin
是 https://websiteb.com