Skip to Content Skip to Search
Methods
P
S

Instance Public methods

protect_from_forgery(options = {})

Turn on request forgery protection. Bear in mind that GET and HEAD requests are not checked.

class ApplicationController < ActionController::Base
  protect_from_forgery
end

class FooController < ApplicationController
  protect_from_forgery except: :index
end

You can disable forgery protection on a controller using skip_forgery_protection:

class BarController < ApplicationController
  skip_forgery_protection
end

Valid Options:

  • :only / :except - Only apply forgery protection to a subset of actions. For example only: [ :create, :create_all ].

  • :if / :unless - Turn off the forgery protection entirely depending on the passed Proc or method reference.

  • :prepend - By default, the verification of the authentication token will be added at the position of the protect_from_forgery call in your application. This means any callbacks added before are run first. This is useful when you want your forgery protection to depend on other callbacks, like authentication methods (Oauth vs Cookie auth).

    If you need to add verification to the beginning of the callback chain, use prepend: true.

  • :with - Set the method to handle unverified request. If not specified, defaults to the value of config.action_controller.default_protect_from_forgery_with, which is :null_session by default but will change to :exception in a future version of Rails. You can opt into the new behavior now by setting config.action_controller.default_protect_from_forgery_with = :exception. Note if default_protect_from_forgery is true, Rails calls protect_from_forgery with with: :exception.

Built-in unverified request handling methods are:

  • :exception - Raises ActionController::InvalidCrossOriginRequest exception.

  • :reset_session - Resets the session.

  • :null_session - Provides an empty session during request but doesn’t reset it completely. Currently used as default if :with option is not specified, but this will change to :exception in a future version of Rails.

You can also implement custom strategy classes for unverified request handling:

class CustomStrategy
  def initialize(controller)
    @controller = controller
  end

  def handle_unverified_request
    # Custom behavior for unverfied request
  end
end

class ApplicationController < ActionController::Base
  protect_from_forgery with: CustomStrategy
end
  • :store - Set the strategy to store and retrieve CSRF tokens.

Built-in session token strategies are:

  • :session - Store the CSRF token in the session. Used as default if :store option is not specified.

  • :cookie - Store the CSRF token in an encrypted cookie.

You can also implement custom strategy classes for CSRF token storage:

class CustomStore
  def fetch(request)
    # Return the token from a custom location
  end

  def store(request, csrf_token)
    # Store the token in a custom location
  end

  def reset(request)
    # Delete the stored session token
  end
end

class ApplicationController < ActionController::Base
  protect_from_forgery store: CustomStore.new
end
  • :using - Set the verification strategy for CSRF protection.

    Built-in verification strategies are:

    • :header_only - Uses the Sec-Fetch-Site header sent by modern browsers to verify that requests originate from the same site. This approach does not require authenticity tokens but only works with browsers that support the Fetch Metadata Request Headers. Requests without a valid Sec-Fetch-Site header will be rejected. This is the default.

    • :header_or_legacy_token - A hybrid approach that first checks the Sec-Fetch-Site header. If the header indicates same-site or same-origin, the request is allowed. Requests with a cross-site value are rejected. When the header is missing or “none”, it falls back to checking the authenticity token. This mode logs when falling back to help identify requests that should be fixed to work with :header_only. Use this if you need to support older browsers that don’t send the Sec-Fetch-Site header.

  • :trusted_origins - Array of origins to allow for cross-site requests, such as OAuth/SSO callbacks, third-party embeds, and legitimate remote form submission.

Example:

class ApplicationController < ActionController::Base
  # Modern browsers only (default)
  protect_from_forgery using: :header_only, with: :exception

  # Hybrid approach with fallback for older browsers
  protect_from_forgery using: :header_or_legacy_token, with: :exception

  # Allow cross-site requests from trusted origins
  protect_from_forgery trusted_origins: %w[ https://accounts.google.com ]
end
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 277
      def protect_from_forgery(options = {})
        options = options.reverse_merge(prepend: false)

        strategy = if options.key?(:with)
          options[:with]
        else
          if default_protect_from_forgery_with == :null_session
            ActionController.deprecator.warn(<<~MSG.squish)
              Calling `protect_from_forgery` without specifying a strategy is deprecated
              and will default to `with: :exception` in a future version of Rails. To opt into the new
              behavior now, use `config.action_controller.default_protect_from_forgery_with = :exception`.
              To silence this warning without changing behavior, explicitly pass
              `protect_from_forgery with: :null_session`.
            MSG
          end
          default_protect_from_forgery_with
        end

        self.forgery_protection_strategy = protection_method_class(strategy)
        self.request_forgery_protection_token ||= :authenticity_token

        self.csrf_token_storage_strategy = storage_strategy(options[:store] || SessionStore.new)
        self.forgery_protection_verification_strategy = verification_strategy(options[:using] || forgery_protection_verification_strategy)
        self.forgery_protection_trusted_origins = Array(options[:trusted_origins]) if options.key?(:trusted_origins)

        if options[:prepend]
          prepend_before_action :verify_request_for_forgery_protection, options
          prepend_before_action :verify_authenticity_token, options
        else
          before_action :verify_authenticity_token, :verify_request_for_forgery_protection, options
        end
        append_after_action :verify_same_origin_request
        append_after_action :append_sec_fetch_site_to_vary_header, options
      end

skip_forgery_protection(options = {})

Turn off request forgery protection. This is a wrapper for:

skip_before_action :verify_request_for_forgery_protection
skip_after_action :append_sec_fetch_site_to_vary_header

See skip_before_action for allowed options.

# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 318
def skip_forgery_protection(options = {})
  options = options.reverse_merge(raise: false)
  skip_before_action :verify_request_for_forgery_protection, options
  skip_after_action :append_sec_fetch_site_to_vary_header, options
end