Ruby On Rails框架包含的功能可以轻松构建公开Web服务API的服务器应用程序。例如,控制器执行以下操作:您在Web浏览器CSRF在Rails应用程序中提供HTML并为其他客户端(如iOS)提供API
respond_to :html, :json, :xml
def show
@thing = Thing.find(params[:id])
respond_with @thing
end
...将负责“秀”的行动,再次提供HTML,也渲染请求项目“@thing”为JSON或XML是指定这种数据格式。
在此特定示例中,基于GET的“显示”操作不涉及任何特殊的安全措施。现在考虑一个类似于上述情况的例子,但是对于诸如“创建”或“更新”之类的操作 - 由(模拟)PUT或(实际)POST请求激活的事情。现在CSRF保护起作用。
这里,可悲的是Rails的似乎只有被设计为应对来自JavaScript代码“API调用”(非HTML格式的响应)同一个域的网页内执行,对任何可将HTML内容提供给Web浏览器客户端的控制器,其中CSRF保护是强制性的。 JavaScript代码可以查找Rails包含的魔术'meta'标签,读取CSRF令牌并将其提交回XHR调用,调用基于POST的操作或类似的服务器。
但对于外部呼叫者?如果我们的Rails支持一个网站,但是我们想要创建一个原生的iOS或Android应用程序来与同一个头端进行对话,该怎么办?该应用程序将进行服务调用 - 很好,Rails使这一切变得简单 - 但是任何修改服务器数据的尝试都会失败,因为我们没有CSRF令牌。 我们不能仅仅绕过CSRF保护,因为相同的控制器代码处理Web浏览器以及“纯API”客户端。
与Rails和API调用有关的CSRF问题的所有答案似乎假设你将有这种情况下不同的控制器。但这很愚蠢 - 如果只能用于网页中的JavaScript代码,那么所有“将应用程序作为服务公开”这一点很容易,除非您在使用CSRF的特殊控制器中重复使用一堆代码允许非Web客户端?这种额外的控制器只会增加攻击面。
有没有人知道推荐的“正确”模式来处理Rails应用程序中的CSRF保护,这些应用程序可能由Web浏览器或非Web浏览器客户端(如本机iOS或Android应用程序)“调用”?诸如“respond_with(...)”之类的内置东西不会像总是生成一个JSON/XML对象那样有用,它将CSRF标记作为一个无所不在的字段。我能想到的最好的办法就是自己去做,例如渲染“@thing”为:
{
csrf: "abcdef...7890",
object: { ...JSON representation of @thing... }
}
...但是这似乎是一个黑客位,相当多的工作的,它似乎绕过CSRF世界+狗宣布在每一个最近的令牌无论如何请求。有必须是:-)
是的,Rails改变了对* all *这样的请求运行过滤器,Rails更改的情况经常出现,这几乎是“我们做到了,把它弄糟了”。爱上象牙塔!无论如何...谢谢,我会看看过滤器。它可能不是向前兼容的,但Rails无论如何总是打破它的API。我似乎花更少的时间编写有用的代码,而不是修补应用程序,因为Rails已经改变了其公开的,记录在案的API,使得调用者能够清楚地遵守API。我当然可以明白为什么Rails会遭受如此多的弃用软件的困扰;) – 2012-08-24 15:25:12