mirror of
https://github.com/discourse/discourse.git
synced 2025-03-24 18:15:43 +08:00
SECURITY: properly validate return URL for SSO
Previously carefully crafted URLs could redirect off site
This commit is contained in:
parent
bb3f8e32e5
commit
40ac895ef7
@ -174,7 +174,7 @@ class SessionController < ApplicationController
|
||||
begin
|
||||
uri = URI(return_path)
|
||||
if (uri.hostname == Discourse.current_hostname)
|
||||
return_path = uri.request_uri
|
||||
return_path = uri.to_s
|
||||
elsif !SiteSetting.sso_allows_all_return_paths
|
||||
return_path = path("/")
|
||||
end
|
||||
@ -183,8 +183,10 @@ class SessionController < ApplicationController
|
||||
end
|
||||
end
|
||||
|
||||
# never redirects back to sso in an sso loop
|
||||
if return_path.start_with?(path("/session/sso"))
|
||||
# this can be done more surgically with a regex
|
||||
# but it the edge case of never supporting redirects back to
|
||||
# any url with `/session/sso` in it anywhere is reasonable
|
||||
if return_path.include?(path("/session/sso"))
|
||||
return_path = path("/")
|
||||
end
|
||||
|
||||
|
@ -403,6 +403,17 @@ RSpec.describe SessionController do
|
||||
expect(logged_on_user.admin).to eq(true)
|
||||
end
|
||||
|
||||
it 'does not redirect offsite' do
|
||||
sso = get_sso("#{Discourse.base_url}//site.com/xyz")
|
||||
sso.external_id = '666'
|
||||
sso.email = 'bob@bob.com'
|
||||
sso.name = 'Sam Saffron'
|
||||
sso.username = 'sam'
|
||||
|
||||
get "/session/sso_login", params: Rack::Utils.parse_query(sso.payload), headers: headers
|
||||
expect(response).to redirect_to("#{Discourse.base_url}//site.com/xyz")
|
||||
end
|
||||
|
||||
it 'redirects to a non-relative url' do
|
||||
sso = get_sso("#{Discourse.base_url}/b/")
|
||||
sso.external_id = '666' # the number of the beast
|
||||
|
Loading…
x
Reference in New Issue
Block a user