aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_controller/metal/request_forgery_protection.rb
diff options
context:
space:
mode:
authorBen Toews <mastahyeti@users.noreply.github.com>2015-11-25 15:06:12 -0700
committerBen Toews <mastahyeti@users.noreply.github.com>2015-11-25 15:06:12 -0700
commit85783534fcf1baefa5b502a2bfee235ae6d612d7 (patch)
tree64c3c3fe095f7da41c309a238f1c02186eccd08f /actionpack/lib/action_controller/metal/request_forgery_protection.rb
parentcb67c819338d75c07a591dc23759747c740a5088 (diff)
downloadrails-85783534fcf1baefa5b502a2bfee235ae6d612d7.tar.gz
rails-85783534fcf1baefa5b502a2bfee235ae6d612d7.tar.bz2
rails-85783534fcf1baefa5b502a2bfee235ae6d612d7.zip
Add option to verify Origin header in CSRF checks
Diffstat (limited to 'actionpack/lib/action_controller/metal/request_forgery_protection.rb')
-rw-r--r--actionpack/lib/action_controller/metal/request_forgery_protection.rb30
1 files changed, 28 insertions, 2 deletions
diff --git a/actionpack/lib/action_controller/metal/request_forgery_protection.rb b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
index 64f6f7cf51..836ed892dc 100644
--- a/actionpack/lib/action_controller/metal/request_forgery_protection.rb
+++ b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
@@ -77,6 +77,10 @@ module ActionController #:nodoc:
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
+
helper_method :form_authenticity_token
helper_method :protect_against_forgery?
end
@@ -257,8 +261,19 @@ module ActionController #:nodoc:
# * Does the X-CSRF-Token header match the form_authenticity_token
def verified_request?
!protect_against_forgery? || request.get? || request.head? ||
- valid_authenticity_token?(session, form_authenticity_param) ||
- valid_authenticity_token?(session, request.headers['X-CSRF-Token'])
+ (valid_request_origin? && any_authenticity_token_valid?)
+ end
+
+ # Checks if any of the authenticity tokens from the request are valid.
+ def any_authenticity_token_valid?
+ request_authenticity_tokens.any? do |token|
+ valid_authenticity_token?(session, token)
+ end
+ end
+
+ # Possible authenticity tokens sent in the request.
+ def request_authenticity_tokens
+ [form_authenticity_param, request.x_csrf_token]
end
# Sets the token value for the current session.
@@ -336,5 +351,16 @@ module ActionController #:nodoc:
def protect_against_forgery?
allow_forgery_protection
end
+
+ # Checks if the request originated from the same origin by looking at the
+ # Origin header.
+ def valid_request_origin?
+ if forgery_protection_origin_check
+ # We accept blank origin headers because some user agents don't send it.
+ request.origin.nil? || request.origin == request.base_url
+ else
+ true
+ end
+ end
end
end