CSRF Token

定义

CSRF: cross-site request forgery(跨站点请求伪造)

导致的原因

这要从Cookie的作用来讲起。我们知道HTTP请求是无状态的,但是在实际的web应用中,我们需要请求是有状态的,比如我们需要记住登录的状态,不用每一个请求都重新登录。想要实现这样的需求我们就需要Cookie。

Cookie在服务器端通过Set-Cookie来设置需要存储在Cookie的值,然后存储在客户端(浏览器)。之后在客户端发起的任何指向同一个domain的请求中,都会带上这些Cookie的信息。

那么问题就来了,这里只要是针对同一个domain的请求都会带上cookie,但是并不限制这些请求是从哪里发起的。

我们来看看下面的场景:
CSRF Token_第1张图片

至此,我们应该对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_urlrequest.origin的比较。
这里base_url指的是这次请求的domain地址,origin指的是这个请求是从哪里来的。
请看下面的例子:
假设我们在站点Bhttps://websiteb.com触发了一个到站点Ahttps://websitea.com的请求:
POST https://websitea.com/path
那么此时在A的server:
request.base_urlhttps://websitea.com
request.originhttps://websiteb.com

你可能感兴趣的:(CSRF Token)