Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Arcila Valenzuela <sarcila@gitlab.com>2019-08-19 16:19:19 +0300
committerYorick Peterse <yorick@yorickpeterse.com>2019-09-30 15:22:06 +0300
commit3692e9f8a23386c627942ca2a9edd8c00af7e904 (patch)
tree0d092bdbdfc954e1a9e2b520291a7244c0cd679e /lib/gitlab/auth
parent010e3c5ed41db96f68549e01373a9aacadd995d7 (diff)
Validate that SAML requests are originated from gitlab
If the request wasn't initiated by gitlab we shouldn't add the new identity to the user, and instead show that we weren't able to link the identity to the user. This should fix: https://gitlab.com/gitlab-org/gitlab-ce/issues/56509
Diffstat (limited to 'lib/gitlab/auth')
-rw-r--r--lib/gitlab/auth/omniauth_identity_linker_base.rb5
-rw-r--r--lib/gitlab/auth/saml/identity_linker.rb24
-rw-r--r--lib/gitlab/auth/saml/origin_validator.rb41
3 files changed, 68 insertions, 2 deletions
diff --git a/lib/gitlab/auth/omniauth_identity_linker_base.rb b/lib/gitlab/auth/omniauth_identity_linker_base.rb
index c620fc5d6bd..a6c247f31a7 100644
--- a/lib/gitlab/auth/omniauth_identity_linker_base.rb
+++ b/lib/gitlab/auth/omniauth_identity_linker_base.rb
@@ -3,12 +3,13 @@
module Gitlab
module Auth
class OmniauthIdentityLinkerBase
- attr_reader :current_user, :oauth
+ attr_reader :current_user, :oauth, :session
- def initialize(current_user, oauth)
+ def initialize(current_user, oauth, session = {})
@current_user = current_user
@oauth = oauth
@changed = false
+ @session = session
end
def link
diff --git a/lib/gitlab/auth/saml/identity_linker.rb b/lib/gitlab/auth/saml/identity_linker.rb
index ae0d6dded4e..93195c3189f 100644
--- a/lib/gitlab/auth/saml/identity_linker.rb
+++ b/lib/gitlab/auth/saml/identity_linker.rb
@@ -4,6 +4,30 @@ module Gitlab
module Auth
module Saml
class IdentityLinker < OmniauthIdentityLinkerBase
+ extend ::Gitlab::Utils::Override
+
+ UnverifiedRequest = Class.new(StandardError)
+
+ override :link
+ def link
+ raise_unless_request_is_gitlab_initiated! if unlinked?
+
+ super
+ end
+
+ protected
+
+ def raise_unless_request_is_gitlab_initiated!
+ raise UnverifiedRequest unless valid_gitlab_initiated_request?
+ end
+
+ def valid_gitlab_initiated_request?
+ OriginValidator.new(session).gitlab_initiated?(saml_response)
+ end
+
+ def saml_response
+ oauth.fetch(:extra, {}).fetch(:response_object, {})
+ end
end
end
end
diff --git a/lib/gitlab/auth/saml/origin_validator.rb b/lib/gitlab/auth/saml/origin_validator.rb
new file mode 100644
index 00000000000..4ecc688888f
--- /dev/null
+++ b/lib/gitlab/auth/saml/origin_validator.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Auth
+ module Saml
+ class OriginValidator
+ AUTH_REQUEST_SESSION_KEY = "last_authn_request_id".freeze
+
+ def initialize(session)
+ @session = session || {}
+ end
+
+ def store_origin(authn_request)
+ session[AUTH_REQUEST_SESSION_KEY] = authn_request.uuid
+ end
+
+ def gitlab_initiated?(saml_response)
+ return false if identity_provider_initiated?(saml_response)
+
+ matches?(saml_response)
+ end
+
+ private
+
+ attr_reader :session
+
+ def matches?(saml_response)
+ saml_response.in_response_to == expected_request_id
+ end
+
+ def identity_provider_initiated?(saml_response)
+ saml_response.in_response_to.blank?
+ end
+
+ def expected_request_id
+ session[AUTH_REQUEST_SESSION_KEY]
+ end
+ end
+ end
+ end
+end