url_for is useful for generating routes from a Hash, but can lead to an .
Imagine your application contains code that checks if the current request's path is what it would generate internally.
If different, it would redirect users to the generated/expected path.
expected_path = url_for(params.to_unsafe_h) if expected_path != request.original_fullpath redirect_to expected_path end
This works, but doing it like that you've just introduced an Open Redirect vulnerability.
It's as simple as passing a
host=evil.tld URL parameter. Rails would see
url_for(..., host: "evil.tld") and happily generate a URL to that foreign host.
This makes phishing much easier, because an attacker can use links with your application's hostname, cause a redirect to
evil.tld and present a sign-in form which looks like yours. Users will enter their login credentials and submit them to
request.path_parameters. That will exclude values like
:only_path, etc and is safe to generate paths inside your application. Note that it does not include query parameters.
redirect_to(url, allow_other_host: false)to avoid redirecting to foreign hosts. Careful: this only works for
redirect_to. If you say e.g.
link_to expected_pathyou'll still generate a link to a foreign host.
exclude, like so:
url_for(params.to_unsafe_h.exclude(:host, :protocol)). To feel extra safe, you can add
merge(only_path: true)but excluding
:hostshould have taken care of that.
In Rails 7 applications,
redirect_to defaults to
If you want to redirect to foreign hosts, you must specify
allow_other_host: true instead.
As mentioned above, this helps only with
redirect_to, not if you place such URLs in links or similar.