关于ruby-on-rails:CSRF-Token

52次阅读

共计 1062 个字符,预计需要花费 3 分钟才能阅读完成。

定义

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_urlrequest.origin 的比拟。
这里 base_url 指的是这次申请的 domain 地址,origin 指的是这个申请是从哪里来的。
请看上面的例子:
假如咱们在站点 B https://websiteb.com触发了一个到站点 A https://websitea.com的申请:
POST https://websitea.com/path
那么此时在 A 的 server:
request.base_urlhttps://websitea.com
request.originhttps://websiteb.com

正文完
 0