【问题标题】:Correct use of protect_from_forgery in Rails app serving Web and API在提供 Web 和 API 的 Rails 应用程序中正确使用protect_from_forgery
【发布时间】:2016-03-15 11:17:45
【问题描述】:

我正在开发一个 Rails 4 应用程序,该应用程序通过 API 为移动应用程序提供服务,并有一个 Web UI 供管理员管理应用程序。用户还将看到几个网页(成功的电子邮件确认和重置密码)。

我创建了两组控制器:一组继承自 APIController,另一组继承自 AdminController。这两个都继承自 ApplicationController。负责面向用户的网页的其余控制器也继承自 ApplicationController。

鉴于此方案,我不确定如何使用protect_from_forgery 正确实施CSRF 保护。我目前有以下:

class ApplicationController < ActionController::Base
  # ...
end

module API
  class APIController < ApplicationController
    protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format == 'application/json' }
    # ...
  end
end

module Admin
  class AdminController < ApplicationController
    protect_from_forgery with: :exception
    # ...
  end
end

class UsersController < ApplicationController
  protect_from_forgery with: :exception
  # ...
end

所以我的问题是:这是正确的吗?有什么办法可以改善吗? APIController 中的检查是否毫无意义,因为所有 API 请求都只是 JSON?

Brakeman 抱怨 ApplicationController 中没有protect_from_forgery 调用,但可能在子类中没有看到调用。

提前致谢!

【问题讨论】:

    标签: ruby-on-rails-4 csrf-protection


    【解决方案1】:

    您可以看到here, on their (brakeman) Github page 仅检查ApplicationController 上的存在

    您的管理员和用户控制器可以使用 protect_from_forgery with: :exception

    Rails 4 上protect_from_forgery 的默认行为是:null_session,如果需要,您可以删除选项with:

    关于改进,我将实现一种在用户中保存令牌并匹配每个请求的方法,这样请求 API 的用户将不得不在每个请求中发送他的令牌。这样做可以避免获取 CSRF 令牌,然后使用该令牌发送请求。例如,对于移动用户,这是一个额外的请求,您只需保存正确的令牌即可解决。如果有人得到这个令牌,它可以作为用户传递并更改数据。但是您可以寻找更多方法来提高安全性。

    如果您将令牌保存在会话或 cookie 中,则可能会发生 CSRF,如果您选择这样保存,则必须独立处理。

    如果你打算使用移动端的API,将令牌(按照我先说的策略)保存在移动端(内存或本地数据库)上会更安全。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-15
      • 2015-04-24
      • 1970-01-01
      • 2015-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多