2012-02-04 93 views
11

我们的rails3应用程序与另一个作​​为REST函数公开的rails应用程序通信。在对REST服务进行的所有POST调用中,我们将以下警告过渡到rails3。如何在rails应用程序之间传递CSRF令牌

WARNING: Can't verify CSRF token authenticity 

我们应该如何通过电线上的CSRF令牌,当我们做一个POST调用REST服务,在ApplicationController中有protect_from_forgery方法和调用也登陆上handle_unverified_request通话。我们使用HTTP基本身份验证进行身份验证,它似乎工作正常。我们应该怎样做才能解决这个问题。

+0

是两个应用程序的后端之间的通信还是有可能为“前端”用户直接调用REST功能? – sled 2012-02-04 14:56:00

+0

UI调用一个按钮操作,这又会导致控制器将此调用发送到REST服务。控制器的 – Sam 2012-02-04 16:22:15

+0

您的意思是应用程序A的轨道控制器向应用程序B的控制器发出请求? – sled 2012-02-04 17:40:28

回答

9

好了,现在我会给它一个答案来回答你的问题。

CSRF令牌是“会话相关”,这意味着用户必须与他正在与之通信的应用程序共享会话。这意味着必须在提交实际表单之前提出请求,这是在提交表单之前显示表单的标准HTML表单的情况,因此有足够空间为此用户生成CSRF标记。

让我们调用服务于UI按钮App1的应用程序和托管REST服务App2的应用程序。

用户与App1共享会话并获取App1提供的UI按钮。一旦用户点击该按钮,就向App1发出请求,并且App1向App2的REST服务发出请求。

结论:用户不会与App2共享会话,但您的App1与App2有会话。最后有两件事:

  1. 用户不容易受到App2上的跨站点伪造攻击,因为他在该服务器上没有会话。因此,如果我在这里发布类似<img src="http://app2.com/rest-service/destroy>的内容,App2不会识别我,因为我不会与App2共享会话,也不会发生任何事情。

  2. 可以实现对REST服务自己的保安措施,公众将其固定:由主要的API

    • 认证通过HTTP基本认证
    • 认证....

这意味着你可以在REST服务下降的CSRF保护和留在S AFE侧只要用户无法通过AJAX等直接调用

加成

CSRF保护您的网站从不是来自你的出身提交的表单(实际上这适用于已发布表单只因为他们通常操纵数据。

最大的情况是:我是攻击者,我想更新您的用户帐户名称为“Mr. Potatoe”,我会这样做的方式是在我的网站上放置隐藏表单,到Yourdomain.com/account与隐藏字段如account[name]="Mr. Potatoe"。现在没有CSRF保护会发生什么?我的浏览器提交表单,并发送认证cookie,我的名字现在是“Mr. Potatoe”。 CSRF保护会发生什么?我的浏览器提交表单并发送cookie,但表单没有CSRF令牌,因此请求被拒绝。在这种情况下,攻击者是否有办法获得CSRF令牌?答案是不。也许你会问自己....

  • 如果我把什么我的网站上隐藏的iframe指向Yourdomain.com/account/edit,只是复制包含令牌的隐藏字段? - 回答:由于相同的原产地政策,它不起作用,如果其内容不是来自您的域,则无法读取iframe中的内容。

  • 如果我在后台进行AJAX调用以获取令牌,该怎么办?答:这不会起作用,因为使用纯粹的AJAX,您也必须遵守相同的原产地政策。

现在让我们切入正题:我无法发送从我的页面隐藏AJAX调用你的伤害你的用户是谁在我的网站。

这是什么意思?您可以实现一个before过滤器,用于检查request.xhr?是否为true或用户代理是否类似“我的REST客户端XY”,因为这不能由>>浏览器< <中的跨站请求伪造。所以如果是这种情况,你可以忽略/禁用CSRF保护。

通过,如果你想使你的网站内的AJAX请求就可以获得CSRF方式令牌是这样的:

var token = $('meta[name="csrf-token"]').attr('content'); 

见的Rails UJS脚本:https://github.com/rails/jquery-ujs/blob/master/src/rails.js#L81

注意:这仅仅保护你从跨网站伪造,没有别的......

+0

有用。但是如果REST服务既可以作为REST服务又可以作为HTML页面调用呢?假设您正在使用ruby编写针对Rails应用程序的测试,并希望能够测试发布表单,但是上面提到的CRSF失败正在发生。好像我们必须获得一个会话并获得CSRF令牌以回传帖子。但是如何? – Dad 2012-04-06 04:15:30

+0

对于测试用例来说,看起来像这样的东西可能会很有用:https://github.com/archiloque/rest-client,因为它让我们得到应该包含CSRF标记的cookie。 (???) – Dad 2012-04-06 04:19:46

+0

Afaik将csrf标记作为隐藏字段嵌入到表单标记中,并将definitley作为标记嵌入部分中。 – sled 2012-04-07 20:16:57