1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Improve logging when Origin header doesn't match

I came up against this while dealing with a misconfigured server. The
browser was setting the Origin header to "https://example.com", but the
Rails app returned "http://example.com" from request.base_url (because
it was failing to detect that HTTPS was used).

This caused verify_authenticity_token to fail, but the message in the
log was "Can't verify CSRF token", which is confusing because the
failure had nothing to do with the CSRF token sent in the request. This
made it very hard to identify the issue, so hopefully this will make it
more obvious for the next person.
This commit is contained in:
Jon Leighton 2017-04-06 16:03:35 +01:00
parent fd097cff79
commit a500b4796f
2 changed files with 16 additions and 1 deletions

View file

@ -213,7 +213,11 @@ module ActionController #:nodoc:
if !verified_request? if !verified_request?
if logger && log_warning_on_csrf_failure if logger && log_warning_on_csrf_failure
if valid_request_origin?
logger.warn "Can't verify CSRF token authenticity." logger.warn "Can't verify CSRF token authenticity."
else
logger.warn "HTTP Origin header (#{request.origin}) didn't match request.base_url (#{request.base_url})"
end
end end
handle_unverified_request handle_unverified_request
end end

View file

@ -347,6 +347,10 @@ module RequestForgeryProtectionTests
end end
def test_should_block_post_with_origin_checking_and_wrong_origin def test_should_block_post_with_origin_checking_and_wrong_origin
old_logger = ActionController::Base.logger
logger = ActiveSupport::LogSubscriber::TestHelper::MockLogger.new
ActionController::Base.logger = logger
forgery_protection_origin_check do forgery_protection_origin_check do
session[:_csrf_token] = @token session[:_csrf_token] = @token
@controller.stub :form_authenticity_token, @token do @controller.stub :form_authenticity_token, @token do
@ -356,6 +360,13 @@ module RequestForgeryProtectionTests
end end
end end
end end
assert_match(
"HTTP Origin header (http://bad.host) didn't match request.base_url (http://test.host)",
logger.logged(:warn).last
)
ensure
ActionController::Base.logger = old_logger
end end
def test_should_warn_on_missing_csrf_token def test_should_warn_on_missing_csrf_token