aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib
diff options
context:
space:
mode:
authorRafael França <rafaelmfranca@gmail.com>2015-11-26 14:23:50 -0200
committerRafael França <rafaelmfranca@gmail.com>2015-11-26 14:23:50 -0200
commite1e6499ede1dd196c03f650b95c3a0098c7c32ff (patch)
tree934b91cfbf3950483900976f42dd827e90edf5a0 /actionpack/lib
parentd25205241b4f8d38b8ab106ffc1c465a8a697415 (diff)
parent85783534fcf1baefa5b502a2bfee235ae6d612d7 (diff)
downloadrails-e1e6499ede1dd196c03f650b95c3a0098c7c32ff.tar.gz
rails-e1e6499ede1dd196c03f650b95c3a0098c7c32ff.tar.bz2
rails-e1e6499ede1dd196c03f650b95c3a0098c7c32ff.zip
Merge pull request #22263 from mastahyeti/csrf-origin-check
Add option to verify Origin header in CSRF checks [Jeremy Daer + Rafael Mendonça França]
Diffstat (limited to 'actionpack/lib')
-rw-r--r--actionpack/lib/action_controller/metal/request_forgery_protection.rb30
-rw-r--r--actionpack/lib/action_dispatch/http/request.rb4
2 files changed, 30 insertions, 4 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
diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb
index bd0f38953a..3280799647 100644
--- a/actionpack/lib/action_dispatch/http/request.rb
+++ b/actionpack/lib/action_dispatch/http/request.rb
@@ -36,8 +36,8 @@ module ActionDispatch
HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING
HTTP_ACCEPT_LANGUAGE HTTP_CACHE_CONTROL HTTP_FROM
HTTP_NEGOTIATE HTTP_PRAGMA HTTP_CLIENT_IP
- HTTP_X_FORWARDED_FOR HTTP_VERSION
- HTTP_X_REQUEST_ID HTTP_X_FORWARDED_HOST
+ HTTP_X_FORWARDED_FOR HTTP_ORIGIN HTTP_VERSION
+ HTTP_X_CSRF_TOKEN HTTP_X_REQUEST_ID HTTP_X_FORWARDED_HOST
SERVER_ADDR
].freeze