I am developing a Rails 4 app that serves a mobile app through an API, and has a web UI for admins to manage the application. There's also a couple of web pages that users will see (successful e-mail confirmation and reset password).
I created two sets of controllers: one set inherits from APIController, and the other from AdminController. Both of these inherit from ApplicationController. The remaining controller responsible for user facing web pages also inherits from ApplicationController.
Given this scheme, I am unsure on how to properly implement CSRF protection with protect_from_forgery. I currently have the following:
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
So my question is: is this correct? Is there any way to improve it? Is the check in the APIController pointless since all API requests will be only JSON anyway?
Brakeman complained that there is no protect_from_forgery call in ApplicationController, but maybe it doesn't see the calls in the subclasses.
Thanks in advance!
You can see here, on their (brakeman) Github page that it checks for the presence on the ApplicationController
only
Your Admin and Users controllers are fine with the protect_from_forgery with: :exception
The default behaviour on Rails 4 for protect_from_forgery
is :null_session
, you could remove the option with:
if you want.
About improving, I would implement a way to save a token in the user and match for every request, that way the user requesting the API would have to send his token every request. Doing this you avoid the necessity in getting the CSRF token and then send the request with this token. For mobile users for example, this is one extra request where you could solve just by saving the right token. If someone get this token though, it could pass as the user and change the data. But you can look for more ways on how to make this more secure.
The CSRF can happen if you save the token in sessions or cookies, you would have to take care of that independently, in case you choose to save like that.
If you intend to use the API for mobiles, save the token(in the strategy I said first) on the mobile(memory or local db) and it will be more safe.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With