在 Rails 应用服务 Web 和 API 中正确使用 protect_from_forgery
Correct use of protect_from_forgery in Rails app serving Web and API
我正在开发一个 Rails 4 应用程序,它通过 API 为移动应用程序提供服务,并有一个网络 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
所以我的问题是:这是正确的吗?有什么办法可以改善吗? API 控制器中的检查是否毫无意义,因为所有 API 请求无论如何都将只有 JSON?
Brakeman 抱怨 ApplicationController 中没有 protect_from_forgery 调用,但也许它没有看到子类中的调用。
提前致谢!
您可以看到 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,将token(我前面说的策略)保存在手机(内存或本地数据库)上,这样会更安全。
我正在开发一个 Rails 4 应用程序,它通过 API 为移动应用程序提供服务,并有一个网络 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
所以我的问题是:这是正确的吗?有什么办法可以改善吗? API 控制器中的检查是否毫无意义,因为所有 API 请求无论如何都将只有 JSON?
Brakeman 抱怨 ApplicationController 中没有 protect_from_forgery 调用,但也许它没有看到子类中的调用。
提前致谢!
您可以看到 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,将token(我前面说的策略)保存在手机(内存或本地数据库)上,这样会更安全。