Module: ActionController::RequestForgeryProtection
Relationships & Source Files | |
Namespace Children | |
Modules:
| |
Classes:
| |
Extension / Inclusion / Inheritance Descendants | |
Included In:
Base ,
::ActionView::TestCase::TestController ,
Rails::ApplicationController,
::Rails::HealthController ,
Rails::InfoController,
Rails::MailersController,
Rails::PwaController,
Rails::WelcomeController
| |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
|
|
Instance Chain:
|
|
Defined in: | actionpack/lib/action_controller/metal/request_forgery_protection.rb |
Overview
Controller actions are protected from Cross-Site Request Forgery (CSRF) attacks by including a token in the rendered HTML for your application. This token is stored as a random string in the session, to which an attacker does not have access. When a request reaches your application, ::Rails
verifies the received token with the token in the session. All requests are checked except GET requests as these should be idempotent. Keep in mind that all session-oriented requests are CSRF protected by default, including JavaScript and HTML requests.
Since HTML and JavaScript requests are typically made from the browser, we need to ensure to verify request authenticity for the web browser. We can use session-oriented authentication for these types of requests, by using the protect_from_forgery
method in our controllers.
GET requests are not protected since they don’t have side effects like writing to the database and don’t leak sensitive information. JavaScript requests are an exception: a third-party site can use a <script> tag to reference a JavaScript URL on your site. When your JavaScript response loads on their site, it executes. With carefully crafted JavaScript on their end, sensitive data in your JavaScript response may be extracted. To prevent this, only XmlHttpRequest (known as XHR or Ajax) requests are allowed to make requests for JavaScript responses.
Subclasses of Base
are protected by default with the :exception
strategy, which raises an InvalidAuthenticityToken
error on unverified requests.
APIs may want to disable this behavior since they are typically designed to be state-less: that is, the request API
client handles the session instead of ::Rails
. One way to achieve this is to use the :null_session
strategy instead, which allows unverified requests to be handled, but with an empty session:
class ApplicationController < ActionController::Base
protect_from_forgery with: :null_session
end
Note that API
only applications don’t include this module or a session middleware by default, and so don’t require CSRF protection to be configured.
The token parameter is named authenticity_token
by default. The name and value of this token must be added to every layout that renders forms by including csrf_meta_tags
in the HTML head
.
Learn more about CSRF attacks and securing your application in the [Ruby on ::Rails
Security Guide](guides.rubyonrails.org/security.html).
Constant Summary
-
AUTHENTICITY_TOKEN_LENGTH =
# File 'actionpack/lib/action_controller/metal/request_forgery_protection.rb', line 45232
-
CROSS_ORIGIN_JAVASCRIPT_WARNING =
private
# File 'actionpack/lib/action_controller/metal/request_forgery_protection.rb', line 417"Security warning: an embedded " \ "<script> tag on another site requested protected JavaScript. " \ "If you know what you're doing, go ahead and disable forgery " \ "protection on this action to permit cross-origin JavaScript embedding."
-
CSRF_TOKEN =
# File 'actionpack/lib/action_controller/metal/request_forgery_protection.rb', line 64"action_controller.csrf_token"
-
GLOBAL_CSRF_TOKEN_IDENTIFIER =
private
# File 'actionpack/lib/action_controller/metal/request_forgery_protection.rb', line 578"!real_csrf_token"
-
NULL_ORIGIN_MESSAGE =
# File 'actionpack/lib/action_controller/metal/request_forgery_protection.rb', line 614<<~MSG The browser returned a 'null' origin for a request with origin-based forgery protection turned on. This usually means you have the 'no-referrer' Referrer-Policy header enabled, or that the request came from a site that refused to give its origin. This makes it impossible for Rails to verify the source of the requests. Likely the best solution is to change your referrer policy to something less strict like same-origin or strict-origin. If you cannot change the referrer policy, you can disable origin checking with the Rails.application.config.action_controller.forgery_protection_origin_check setting. MSG
::ActiveSupport::Callbacks
- Included
::AbstractController::Callbacks
- Attributes & Methods
- .raise_on_missing_callback_actions (also: #raise_on_missing_callback_actions) rw
- #raise_on_missing_callback_actions rw
::AbstractController::Helpers
- Attributes & Methods
Class Method Summary
::ActiveSupport::DescendantsTracker
- self
::ActiveSupport::Concern
- Extended
class_methods | Define class methods from given block. |
included | Evaluate given block in context of base class, so that you can write class macros here. |
prepended | Evaluate given block in context of base class, so that you can write class macros here. |
Instance Attribute Summary
::AbstractController::Callbacks
- Included
Instance Method Summary
::ActiveSupport::Callbacks
- Included
#run_callbacks | Runs the callbacks for the given event. |
::AbstractController::Helpers
- Included
DSL Calls
included
[ GitHub ]71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
# File 'actionpack/lib/action_controller/metal/request_forgery_protection.rb', line 71
included do # Sets the token parameter name for RequestForgery. Calling # `protect_from_forgery` sets it to `:authenticity_token` by default. config_accessor :request_forgery_protection_token self.request_forgery_protection_token ||= :authenticity_token # Holds the class which implements the request forgery protection. config_accessor :forgery_protection_strategy self.forgery_protection_strategy = nil # Controls whether request forgery protection is turned on or not. Turned off by # default only in test mode. config_accessor :allow_forgery_protection self.allow_forgery_protection = true if allow_forgery_protection.nil? # Controls whether a CSRF failure logs a warning. On by default. config_accessor :log_warning_on_csrf_failure self.log_warning_on_csrf_failure = true # Controls whether the Origin header is checked in addition to the CSRF token. config_accessor :forgery_protection_origin_check self.forgery_protection_origin_check = false # Controls whether form-action/method specific CSRF tokens are used. config_accessor :per_form_csrf_tokens self.per_form_csrf_tokens = false # The strategy to use for storing and retrieving CSRF tokens. config_accessor :csrf_token_storage_strategy self.csrf_token_storage_strategy = SessionStore.new helper_method :form_authenticity_token helper_method :protect_against_forgery? end
Class Attribute Details
._helper_methods (rw)
[ GitHub ]# File 'actionpack/lib/abstract_controller/helpers.rb', line 13
class_attribute :_helper_methods, default: Array.new
._helper_methods? ⇒ Boolean
(rw)
[ GitHub ]
# File 'actionpack/lib/abstract_controller/helpers.rb', line 13
class_attribute :_helper_methods, default: Array.new
.raise_on_missing_callback_actions (rw) Also known as: #raise_on_missing_callback_actions
[ GitHub ]# File 'actionpack/lib/abstract_controller/callbacks.rb', line 36
mattr_accessor :raise_on_missing_callback_actions, default: false
Instance Attribute Details
#_helper_methods (rw)
[ GitHub ]# File 'actionpack/lib/abstract_controller/helpers.rb', line 13
class_attribute :_helper_methods, default: Array.new
#_helper_methods? ⇒ Boolean
(rw)
[ GitHub ]
# File 'actionpack/lib/abstract_controller/helpers.rb', line 13
class_attribute :_helper_methods, default: Array.new
#raise_on_missing_callback_actions (rw)
[ GitHub ]# File 'actionpack/lib/abstract_controller/callbacks.rb', line 36
mattr_accessor :raise_on_missing_callback_actions, default: false
Instance Method Details
#commit_csrf_token(request)
[ GitHub ]# File 'actionpack/lib/action_controller/metal/request_forgery_protection.rb', line 374
def commit_csrf_token(request) # :doc: csrf_token = request.env[CSRF_TOKEN] csrf_token_storage_strategy.store(request, csrf_token) unless csrf_token.nil? end
#initialize
[ GitHub ]# File 'actionpack/lib/action_controller/metal/request_forgery_protection.rb', line 364
def initialize(...) super @_marked_for_same_origin_verification = nil end
#reset_csrf_token(request)
[ GitHub ]# File 'actionpack/lib/action_controller/metal/request_forgery_protection.rb', line 369
def reset_csrf_token(request) # :doc: request.env.delete(CSRF_TOKEN) csrf_token_storage_strategy.reset(request) end