diff --git a/app/controllers/static_controller.rb b/app/controllers/static_controller.rb index f29c24b6394..3a452362c18 100644 --- a/app/controllers/static_controller.rb +++ b/app/controllers/static_controller.rb @@ -54,13 +54,21 @@ class StaticController < ApplicationController params.delete(:username) params.delete(:password) - redirect_to( - if params[:redirect].blank? || params[:redirect].match(login_path) - "/" - else - params[:redirect] + destination = "/" + + if params[:redirect].present? && !params[:redirect].match(login_path) + begin + forum_uri = URI(Discourse.base_url) + uri = URI(params[:redirect]) + if uri.path.present? && (uri.host.blank? || uri.host == forum_uri.host) + destination = uri.path + end + rescue URI::InvalidURIError + # Do nothing if the URI is invalid end - ) + end + + redirect_to destination end skip_before_filter :verify_authenticity_token, only: [:cdn_asset] diff --git a/spec/controllers/static_controller_spec.rb b/spec/controllers/static_controller_spec.rb index 4b1a6380500..86c18550343 100644 --- a/spec/controllers/static_controller_spec.rb +++ b/spec/controllers/static_controller_spec.rb @@ -82,6 +82,27 @@ describe StaticController do end end + context 'with a full url' do + it 'redirects to the correct path' do + xhr :post, :enter, redirect: "#{Discourse.base_url}/foo" + expect(response).to redirect_to '/foo' + end + end + + context 'with a full url to someone else' do + it 'redirects to the root path' do + xhr :post, :enter, redirect: "http://eviltrout.com/foo" + expect(response).to redirect_to '/' + end + end + + context 'with an invalid URL' do + it "redirects to the root" do + xhr :post, :enter, redirect: "javascript:alert('trout')" + expect(response).to redirect_to '/' + end + end + context 'when the redirect path is the login page' do it 'redirects to the root url' do xhr :post, :enter, redirect: login_path