mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
configure how unverified request will be handled
can be configured using `:with` option in `protect_from_forgery` method or `request_forgery_protection_method` config option possible values: - :reset_session (default) - :exception new applications are generated with: protect_from_forgery :with => :exception
This commit is contained in:
parent
7638004d7d
commit
245941101b
4 changed files with 37 additions and 9 deletions
|
@ -37,6 +37,10 @@ module ActionController #:nodoc:
|
|||
config_accessor :request_forgery_protection_token
|
||||
self.request_forgery_protection_token ||= :authenticity_token
|
||||
|
||||
# Controls how unverified request will be handled
|
||||
config_accessor :request_forgery_protection_method
|
||||
self.request_forgery_protection_method ||= :reset_session
|
||||
|
||||
# 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?
|
||||
|
@ -64,8 +68,10 @@ module ActionController #:nodoc:
|
|||
# Valid Options:
|
||||
#
|
||||
# * <tt>:only/:except</tt> - Passed to the <tt>before_filter</tt> call. Set which actions are verified.
|
||||
# * <tt>:with</tt> - Set the method to handle unverified request. Valid values: <tt>:exception</tt> and <tt>:reset_session</tt> (default).
|
||||
def protect_from_forgery(options = {})
|
||||
self.request_forgery_protection_token ||= :authenticity_token
|
||||
self.request_forgery_protection_method = options.delete(:with) if options.key?(:with)
|
||||
prepend_before_filter :verify_authenticity_token, options
|
||||
end
|
||||
end
|
||||
|
@ -80,9 +86,19 @@ module ActionController #:nodoc:
|
|||
end
|
||||
|
||||
# This is the method that defines the application behavior when a request is found to be unverified.
|
||||
# By default, \Rails resets the session when it finds an unverified request.
|
||||
# By default, \Rails uses <tt>request_forgery_protection_method</tt> when it finds an unverified request:
|
||||
#
|
||||
# * <tt>:reset_session</tt> - Resets the session.
|
||||
# * <tt>:exception</tt>: - Raises ActionController::InvalidAuthenticityToken exception.
|
||||
def handle_unverified_request
|
||||
reset_session
|
||||
case request_forgery_protection_method
|
||||
when :exception
|
||||
raise ActionController::InvalidAuthenticityToken
|
||||
when :reset_session
|
||||
reset_session
|
||||
else
|
||||
raise ArgumentError, 'Invalid request forgery protection method, use :exception or :reset_session'
|
||||
end
|
||||
end
|
||||
|
||||
# Returns true or false if a request is verified. Checks:
|
||||
|
|
|
@ -43,7 +43,7 @@ class RequestForgeryProtectionController < ActionController::Base
|
|||
protect_from_forgery :only => %w(index meta)
|
||||
end
|
||||
|
||||
class RequestForgeryProtectionControllerUsingOldBehaviour < ActionController::Base
|
||||
class RequestForgeryProtectionControllerUsingException < ActionController::Base
|
||||
include RequestForgeryProtectionActions
|
||||
protect_from_forgery :only => %w(index meta)
|
||||
|
||||
|
@ -215,7 +215,7 @@ class RequestForgeryProtectionControllerTest < ActionController::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
class RequestForgeryProtectionControllerUsingOldBehaviourTest < ActionController::TestCase
|
||||
class RequestForgeryProtectionControllerUsingExceptionTest < ActionController::TestCase
|
||||
include RequestForgeryProtectionTests
|
||||
def assert_blocked
|
||||
assert_raises(ActionController::InvalidAuthenticityToken) do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
class ApplicationController < ActionController::Base
|
||||
protect_from_forgery
|
||||
# prevent CSRF attacks by raising an exception,
|
||||
# if your application has an API, you'll probably need to use :reset_session
|
||||
protect_from_forgery :with => :exception
|
||||
end
|
||||
|
|
|
@ -275,19 +275,23 @@ module ApplicationTests
|
|||
|
||||
require "#{app_path}/config/environment"
|
||||
|
||||
token = "cf50faa3fe97702ca1ae"
|
||||
PostsController.any_instance.stubs(:form_authenticity_token).returns(token)
|
||||
params = {:authenticity_token => token}
|
||||
|
||||
get "/posts/1"
|
||||
assert_match /patch/, last_response.body
|
||||
|
||||
patch "/posts/1"
|
||||
patch "/posts/1", params
|
||||
assert_match /update/, last_response.body
|
||||
|
||||
patch "/posts/1"
|
||||
patch "/posts/1", params
|
||||
assert_equal 200, last_response.status
|
||||
|
||||
put "/posts/1"
|
||||
put "/posts/1", params
|
||||
assert_match /update/, last_response.body
|
||||
|
||||
put "/posts/1"
|
||||
put "/posts/1", params
|
||||
assert_equal 200, last_response.status
|
||||
end
|
||||
|
||||
|
@ -528,6 +532,12 @@ module ApplicationTests
|
|||
end
|
||||
RUBY
|
||||
|
||||
app_file 'app/controllers/application_controller.rb', <<-RUBY
|
||||
class ApplicationController < ActionController::Base
|
||||
protect_from_forgery :with => :reset_session # as we are testing API here
|
||||
end
|
||||
RUBY
|
||||
|
||||
app_file 'app/controllers/posts_controller.rb', <<-RUBY
|
||||
class PostsController < ApplicationController
|
||||
def create
|
||||
|
|
Loading…
Reference in a new issue