Commit c97bcc38 authored by James Edwards-Jones's avatar James Edwards-Jones

Group SAML metadata enabled if token present

Re-enables SAML metadata while ensuring that we don't
reveal private group existance to anonymous users
parent 5dc7222b
---
title: Adds Group SAML metadata endpoint
merge_request: 5782
author:
type: changed
...@@ -22,10 +22,20 @@ module Gitlab ...@@ -22,10 +22,20 @@ module Gitlab
saml_provider && group.feature_available?(:group_saml) saml_provider && group.feature_available?(:group_saml)
end end
def token_discoverable?
return unless group_discovery_token.present?
group_discovery_token == params['token']
end
private private
attr_reader :env attr_reader :env
def group_discovery_token
group&.saml_discovery_token
end
def path_from_callback_path def path_from_callback_path
path = env['PATH_INFO'] path = env['PATH_INFO']
path_regex = Gitlab::PathRegex.saml_callback_regex path_regex = Gitlab::PathRegex.saml_callback_regex
......
...@@ -5,7 +5,11 @@ module OmniAuth ...@@ -5,7 +5,11 @@ module OmniAuth
option :callback_path, ->(env) { callback?(env) } option :callback_path, ->(env) { callback?(env) }
def setup_phase def setup_phase
require_saml_provider if on_subpath?(:metadata)
require_discovery_token
else
require_saml_provider
end
# Set devise scope for custom callback URL # Set devise scope for custom callback URL
env["devise.mapping"] = Devise.mappings[:user] env["devise.mapping"] = Devise.mappings[:user]
...@@ -16,10 +20,14 @@ module OmniAuth ...@@ -16,10 +20,14 @@ module OmniAuth
super super
end end
# Prevent access to SLO and metadata endpoints # Prevent access to SLO endpoints. These make less sense at
# These will need additional work to securely support # group level and would need additional work to securely support
def other_phase def other_phase
call_app! if on_subpath?(:metadata)
super
else
call_app!
end
end end
def self.invalid_group!(path) def self.invalid_group!(path)
...@@ -41,6 +49,12 @@ module OmniAuth ...@@ -41,6 +49,12 @@ module OmniAuth
self.class.invalid_group!(group_lookup.path) self.class.invalid_group!(group_lookup.path)
end end
end end
def require_discovery_token
unless group_lookup.token_discoverable?
self.class.invalid_group!(group_lookup.path)
end
end
end end
end end
end end
...@@ -58,4 +58,33 @@ describe Gitlab::Auth::GroupSaml::GroupLookup do ...@@ -58,4 +58,33 @@ describe Gitlab::Auth::GroupSaml::GroupLookup do
expect(subject.saml_provider).to be_a(SamlProvider) expect(subject.saml_provider).to be_a(SamlProvider)
end end
context 'on metadata path' do
let(:path_info) { '/users/auth/group_saml/metadata' }
let(:saml_provider) { create(:saml_provider) }
let(:group) { saml_provider.group }
let(:group_params) { { group_path: group.full_path } }
describe '#token_discoverable?' do
it 'returns false when missing the discovery token' do
subject("QUERY_STRING" => group_params.to_query)
expect(subject).not_to be_token_discoverable
end
it 'returns false for incorrect discovery token' do
query_string = group_params.merge(token: 'wrongtoken').to_query
subject("QUERY_STRING" => query_string)
expect(subject).not_to be_token_discoverable
end
it 'returns true when discovery token matches' do
query_string = group_params.merge(token: group.saml_discovery_token).to_query
subject("QUERY_STRING" => query_string)
expect(subject).to be_token_discoverable
end
end
end
end end
...@@ -114,15 +114,42 @@ describe OmniAuth::Strategies::GroupSaml, type: :strategy do ...@@ -114,15 +114,42 @@ describe OmniAuth::Strategies::GroupSaml, type: :strategy do
describe 'POST /users/auth/group_saml/metadata' do describe 'POST /users/auth/group_saml/metadata' do
it 'returns 404 when the group is not found' do it 'returns 404 when the group is not found' do
post '/users/auth/group_saml/metadata', group_path: 'not-a-group' expect do
post '/users/auth/group_saml/metadata', group_path: 'not-a-group'
expect(last_response).to be_not_found end.to raise_error(ActionController::RoutingError)
end end
it 'returns 404 to avoid disclosing group existence' do it 'returns 404 to avoid disclosing group existence' do
post '/users/auth/group_saml/metadata', group_path: 'my-group' expect do
post '/users/auth/group_saml/metadata', group_path: 'my-group'
end.to raise_error(ActionController::RoutingError)
end
expect(last_response).to be_not_found it 'returns metadata when a valid token is provided' do
post '/users/auth/group_saml/metadata', group_path: 'my-group', token: group.saml_discovery_token
expect(last_response.status).to eq 200
expect(last_response.body).to start_with('<?xml')
expect(last_response.header["Content-Type"]).to eq "application/xml"
end
it 'returns 404 when an invalid token is provided' do
expect do
post '/users/auth/group_saml/metadata', group_path: 'my-group', token: 'invalidtoken'
end.to raise_error(ActionController::RoutingError)
end
it 'returns 404 when if group is not found but a token is provided' do
expect do
post '/users/auth/group_saml/metadata', group_path: 'not-a-group', token: 'dummytoken'
end.to raise_error(ActionController::RoutingError)
end
it 'sets omniauth setings from default settings' do
post '/users/auth/group_saml/metadata', group_path: 'my-group', token: group.saml_discovery_token
options = last_request.env['omniauth.strategy'].options
expect(options['assertion_consumer_service_url']).to end_with "/groups/my-group/-/saml/callback"
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment