When you access a Rails controller from another page, the originating URL is sent to the server as the referrer
. In previous versions of Rails, the redirect_back
query parameter with allow_other_host
set as true
could allow a vulnerability for an attacker to override this parameter and force the user to a malicious page.
Before Rails 7.0, the most common solution to this was to set the allow_other_host
to false
.
1
2
3
4
5
# This will redirect back to the source page
redirect_back(fallback_path: "/")
# This will not redirect back to the source page
redirect_back(fallback_path: "/", allow_other_host: false)
However, there still was a need to raise errors on unpermitted open redirects. With the Rails 7.0 ability to identify if the URL is internal and safe to redirect, the chance of compromising the referrer
has become low. This works best for authentication, as in previous versions a compromised params[:return_to]
could have led users to unsafe locations and provoked a credentials breach.
In Rails 7.0 the problem is solved by setting a url_from
method in private:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class PostsController < ApplicationController
def create
@post = Post.new(post_params)
if @post.save
redirect_to return_url
else
render :new, status: :unprocessable_entity
end
end
private
def return_url
url_from(params[:return_to]) || @post
end
def post_params
params.require(:post).permit(:title, :body)
end
end
The url_from
method is new in Rails 7 and should not be confused with url_for
which generates an internal URL from within the app.