什么是Rails中的真实性令牌?


当前回答

什么是authentication_token ?

这是一个由rails应用程序使用的随机字符串,以确保用户是从应用程序页面请求或执行操作,而不是从其他应用程序或站点。

为什么authentication_token是必要的?

保护您的应用程序或站点免受跨站点请求伪造。

如何将authentication_token添加到表单?

如果您使用form_for标记生成表单,则会自动添加authentication_token,否则您可以使用<%= csrf_meta_tag %>。

其他回答

真实性令牌是rails防止“跨站请求伪造(CSRF或XSRF)攻击”的方法。

简单地说,它确保对web应用程序的put / POST / DELETE(可以修改内容的方法)请求是由客户端浏览器发出的,而不是来自第三方(攻击者),后者有权访问在客户端创建的cookie。

什么是authentication_token ?

这是一个由rails应用程序使用的随机字符串,以确保用户是从应用程序页面请求或执行操作,而不是从其他应用程序或站点。

为什么authentication_token是必要的?

保护您的应用程序或站点免受跨站点请求伪造。

如何将authentication_token添加到表单?

如果您使用form_for标记生成表单,则会自动添加authentication_token,否则您可以使用<%= csrf_meta_tag %>。

真实性令牌用于防止跨站点请求伪造攻击(Cross-Site Request Forgery attack, CSRF)。要理解真实性令牌,首先必须理解CSRF攻击。

CSRF

假设你是bank.example的作者。您的网站上有一个表单,用于通过GET请求将资金转移到不同的帐户:

黑客只需向服务器发送一个HTTP请求GET /transfer?数量= $ 1000000 &account-to = 999999,对吧?

错了。黑客的攻击没用。服务器基本上会想?

嗯?这个想要转移的人是谁。肯定不是账户的主人。

服务器如何知道这一点?因为没有session_id cookie来验证请求者。

当你用用户名和密码登录时,服务器会在你的浏览器上设置一个session_id cookie。这样,您就不必用用户名和密码验证每个请求。当你的浏览器发送session_id cookie时,服务器知道:

哦,那是无名氏。他在两分半钟前成功登陆。他可以出发了。

黑客可能会想:

嗯。正常的HTTP请求不会起作用,但如果我能得到session_id cookie,我就很好了。

用户浏览器为银行设置了一堆cookie。域的例子。每次用户向银行提出请求时。例如域,所有的cookie都会被发送。包括session_id cookie。

因此,如果黑客能够让您发出get请求,将资金转移到他的帐户,他就成功了。他怎么能骗你这么做呢? 与跨站点请求伪造。

其实很简单。黑客可以让你访问他的网站。在他的网站上,他可以有以下图片标签:

<img src="http://bank.example/transfer?amount=$1000000&account-to=999999">

当用户的浏览器遇到图像标记时,它将向该url发出GET请求。由于请求来自他的浏览器,它将发送与bank.example相关的所有cookie。如果用户最近登录了银行。session_id cookie将被设置,服务器将认为用户打算转移$1,000,000到帐户999999!

嗯,只要不去危险的地方,你就会没事的。

这还不够。如果有人把这张照片发到Facebook上,出现在你的留声板上怎么办?如果它是通过XSS攻击注入到您正在访问的站点中呢?

没那么糟。只有GET请求是脆弱的。

不正确的。可以动态生成发送POST请求的表单。下面是来自Rails安全指南的例子:

<a href="http://www.harmless.example/" onclick="
  var f = document.createElement('form');
  f.style.display = 'none';
  this.parentNode.appendChild(f);
  f.method = 'POST';
  f.action = 'http://www.example.com/account/destroy';
  f.submit();
  return false;">To the harmless survey</a>

真实性令牌

当你的ApplicationController有这个:

protect_from_forgery with: :exception

这样的:

<%= form_tag do %>
  Form contents
<% end %>

编译成:

<form accept-charset="UTF-8" action="/" method="post">
  <input name="utf8" type="hidden" value="&#x2713;" />
  <input name="authenticity_token" type="hidden" value="J7CBxfHalt49OSHp27hblqK20c9PgwJ108nDHX/8Cts=" />
  Form contents
</form>

具体来说,生成了以下内容:

<input name="authenticity_token" type="hidden" value="J7CBxfHalt49OSHp27hblqK20c9PgwJ108nDHX/8Cts=" />

为了防止CSRF攻击,如果Rails没有看到随请求一起发送的真实性令牌,它就不会认为该请求是安全的。

攻击者如何知道这个令牌是什么?每次生成表单都会随机生成一个不同的值:

跨站点脚本(XSS)攻击——就是这样。但这是不同时期的不同弱点。

真实性令牌的设计使您知道您的表单是从您的网站提交的。它是由运行它的机器生成的,具有唯一的标识符,只有您的机器知道,因此有助于防止跨站请求伪造攻击。

如果您只是在rails拒绝AJAX脚本访问方面遇到困难,那么您可以使用

<%= form_authenticity_token %>

在创建表单时生成正确的令牌。

您可以在文档中阅读更多关于它的信息。

需要authenticity_token的方法

在post, put和delete等幂等方法的情况下需要authenticity_token,因为幂等方法对数据有影响。

为什么需要它

它需要防止邪恶的行为。Authenticity_token存储在会话中,每当在web页面上创建用于创建或更新资源的表单时,真实性令牌存储在隐藏字段中,并与服务器上的表单一起发送。在执行操作之前,用户发送的authenticity_token将与存储在会话中的authenticity_token进行交叉检查。如果authenticity_token相同,则进程继续,否则不执行操作。