New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add allow_other_host option to redirect_back method #30850

Merged
merged 1 commit into from Oct 10, 2017
Jump to file or symbol
Failed to load files and symbols.
+37 −7
Diff settings

Always

Just for now

Add allow_other_host option to redirect_back method

  • Loading branch information...
timsly committed Oct 10, 2017
commit 0db6a14ae16b143e078375ff7f3c940cf707290b
@@ -79,15 +79,18 @@ def redirect_to(options = {}, response_status = {})
# redirect_back fallback_location: "/images/screenshot.jpg"
# redirect_back fallback_location: posts_url
# redirect_back fallback_location: proc { edit_post_url(@post) }
# redirect_back fallback_location: '/', allow_other_host: false
#
# All options that can be passed to <tt>redirect_to</tt> are accepted as
# ==== Options
# * <tt>:fallback_location</tt> - The default fallback location that will be used on missing `Referer` header.
# * <tt>:allow_other_host</tt> - Allows or dissallow redirection to the host that is different to the current host
#
# All other options that can be passed to <tt>redirect_to</tt> are accepted as
# options and the behavior is identical.
def redirect_back(fallback_location:, **args)
if referer = request.headers["Referer"]
redirect_to referer, **args
else
redirect_to fallback_location, **args
end
def redirect_back(fallback_location:, allow_other_host: true, **args)
referer = request.headers["Referer"]
redirect_to_referer = referer && (allow_other_host || _url_host_allowed?(referer))
redirect_to redirect_to_referer ? referer : fallback_location, **args
end
def _compute_redirect_to_location(request, options) #:nodoc:
@@ -120,5 +123,11 @@ def _extract_redirect_to_status(options, response_status)
302
end
end
def _url_host_allowed?(url)
URI(url.to_s).host == request.host
rescue ArgumentError, URI::Error
false
end
end
end
@@ -62,6 +62,10 @@ def redirect_back_with_status
redirect_back(fallback_location: "/things/stuff", status: 307)
end
def safe_redirect_back_with_status
redirect_back(fallback_location: "/things/stuff", status: 307, allow_other_host: false)
end
def host_redirect
redirect_to action: "other_host", only_path: false, host: "other.test.host"
end
@@ -259,6 +263,23 @@ def test_redirect_back_with_no_referer
assert_equal "http://test.host/things/stuff", redirect_to_url
end
def test_safe_redirect_back_from_other_host
@request.env["HTTP_REFERER"] = "http://another.host/coming/from"
get :safe_redirect_back_with_status
assert_response 307
assert_equal "http://test.host/things/stuff", redirect_to_url
end
def test_safe_redirect_back_from_the_same_host
referer = "http://test.host/coming/from"
@request.env["HTTP_REFERER"] = referer
get :safe_redirect_back_with_status
assert_response 307
assert_equal referer, redirect_to_url
end
def test_redirect_to_record
with_routing do |set|
set.draw do
ProTip! Use n and p to navigate between commits in a pull request.