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
|
config_accessor :request_forgery_protection_token
|
||||||
self.request_forgery_protection_token ||= :authenticity_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.
|
# Controls whether request forgery protection is turned on or not. Turned off by default only in test mode.
|
||||||
config_accessor :allow_forgery_protection
|
config_accessor :allow_forgery_protection
|
||||||
self.allow_forgery_protection = true if allow_forgery_protection.nil?
|
self.allow_forgery_protection = true if allow_forgery_protection.nil?
|
||||||
|
@ -64,8 +68,10 @@ module ActionController #:nodoc:
|
||||||
# Valid Options:
|
# Valid Options:
|
||||||
#
|
#
|
||||||
# * <tt>:only/:except</tt> - Passed to the <tt>before_filter</tt> call. Set which actions are verified.
|
# * <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 = {})
|
def protect_from_forgery(options = {})
|
||||||
self.request_forgery_protection_token ||= :authenticity_token
|
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
|
prepend_before_filter :verify_authenticity_token, options
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -80,9 +86,19 @@ module ActionController #:nodoc:
|
||||||
end
|
end
|
||||||
|
|
||||||
# This is the method that defines the application behavior when a request is found to be unverified.
|
# 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
|
def handle_unverified_request
|
||||||
|
case request_forgery_protection_method
|
||||||
|
when :exception
|
||||||
|
raise ActionController::InvalidAuthenticityToken
|
||||||
|
when :reset_session
|
||||||
reset_session
|
reset_session
|
||||||
|
else
|
||||||
|
raise ArgumentError, 'Invalid request forgery protection method, use :exception or :reset_session'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns true or false if a request is verified. Checks:
|
# 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)
|
protect_from_forgery :only => %w(index meta)
|
||||||
end
|
end
|
||||||
|
|
||||||
class RequestForgeryProtectionControllerUsingOldBehaviour < ActionController::Base
|
class RequestForgeryProtectionControllerUsingException < ActionController::Base
|
||||||
include RequestForgeryProtectionActions
|
include RequestForgeryProtectionActions
|
||||||
protect_from_forgery :only => %w(index meta)
|
protect_from_forgery :only => %w(index meta)
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ class RequestForgeryProtectionControllerTest < ActionController::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class RequestForgeryProtectionControllerUsingOldBehaviourTest < ActionController::TestCase
|
class RequestForgeryProtectionControllerUsingExceptionTest < ActionController::TestCase
|
||||||
include RequestForgeryProtectionTests
|
include RequestForgeryProtectionTests
|
||||||
def assert_blocked
|
def assert_blocked
|
||||||
assert_raises(ActionController::InvalidAuthenticityToken) do
|
assert_raises(ActionController::InvalidAuthenticityToken) do
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
class ApplicationController < ActionController::Base
|
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
|
end
|
||||||
|
|
|
@ -275,19 +275,23 @@ module ApplicationTests
|
||||||
|
|
||||||
require "#{app_path}/config/environment"
|
require "#{app_path}/config/environment"
|
||||||
|
|
||||||
|
token = "cf50faa3fe97702ca1ae"
|
||||||
|
PostsController.any_instance.stubs(:form_authenticity_token).returns(token)
|
||||||
|
params = {:authenticity_token => token}
|
||||||
|
|
||||||
get "/posts/1"
|
get "/posts/1"
|
||||||
assert_match /patch/, last_response.body
|
assert_match /patch/, last_response.body
|
||||||
|
|
||||||
patch "/posts/1"
|
patch "/posts/1", params
|
||||||
assert_match /update/, last_response.body
|
assert_match /update/, last_response.body
|
||||||
|
|
||||||
patch "/posts/1"
|
patch "/posts/1", params
|
||||||
assert_equal 200, last_response.status
|
assert_equal 200, last_response.status
|
||||||
|
|
||||||
put "/posts/1"
|
put "/posts/1", params
|
||||||
assert_match /update/, last_response.body
|
assert_match /update/, last_response.body
|
||||||
|
|
||||||
put "/posts/1"
|
put "/posts/1", params
|
||||||
assert_equal 200, last_response.status
|
assert_equal 200, last_response.status
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -528,6 +532,12 @@ module ApplicationTests
|
||||||
end
|
end
|
||||||
RUBY
|
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
|
app_file 'app/controllers/posts_controller.rb', <<-RUBY
|
||||||
class PostsController < ApplicationController
|
class PostsController < ApplicationController
|
||||||
def create
|
def create
|
||||||
|
|
Loading…
Reference in a new issue