CVE-2018-7206 (published 2018-02-18T03:29Z)

An issue was discovered in Project Jupyter JupyterHub OAuthenticator 0.6.x before 0.6.2 and 0.7.x before 0.7.3. When using JupyterHub with GitLab group whitelisting for access control, group membership was not checked correctly, allowing members not in the whitelisted groups to create accounts on the Hub. (Users were not allowed to access other users' accounts, but could create their own accounts on the Hub linked to their GitLab account. GitLab authentication not using gitlab_group_whitelist is unaffected. No other Authenticators are affected.)

Severity: MEDIUM
CVSS v2 base score: 6.5 (AV:N/AC:L/Au:S/C:P/I:P/A:P)
CVSS v3 base score: 8.8, HIGH (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/jupyterhub/oauthenticator
commit_details: repo_url: https://github.com/jupyterhub/oauthenticator
author: Joseph Weston
author_date: 2018-02-16 17:08:58+01:00
msg: Security fix: fix gitlab group whitelist check

check group membership of users

previously, group_whitelist allowed any user who could access the groups in the whitelist,
rather than checking their membership of the groups.

Admin users received the correct behavior already
repository: repo_url: https://github.com/jupyterhub/oauthenticator
repo_name: jupyterhub/oauthenticator
description: OAuth + JupyterHub Authenticator = OAuthenticator
repo_language: Python
owner: jupyterhub
file_changes: filename: gitlab.py
change_type: ModificationType.MODIFY
diff: @@ -21,7 +21,6 @@ from jupyterhub.auth import LocalAuthenticator
 
 from traitlets import Set
 
-from .common import next_page_from_links
 from .oauth2 import OAuthLoginHandler, OAuthenticator
 
 # Support gitlab.com and gitlab community edition installations
@@ -131,31 +130,14 @@ class GitLabOAuthenticator(OAuthenticator):
     def _check_group_whitelist(self, username, user_id, is_admin, access_token):
         http_client = AsyncHTTPClient()
         headers = _api_headers(access_token)
-        if is_admin:
-            # For admins, /groups returns *all* groups. As a workaround
-            # we check if we are a member of each group in the whitelist
-            for group in map(url_escape, self.gitlab_group_whitelist):
-                url = "%s/groups/%s/members/%d" % (GITLAB_API, group, user_id)
-                req = HTTPRequest(url, method="GET", headers=headers)
-                resp = yield http_client.fetch(req, raise_error=False)
-                if resp.code == 200:
-                    return True  # user _is_ in group
-        else:
-            # For regular users we get all the groups to which they have access
-            # and check if any of these are in the whitelisted groups
-            next_page = url_concat("%s/groups" % GITLAB_API,
-                                   dict(all_available=True))
-            while next_page:
-                req = HTTPRequest(next_page, method="GET", headers=headers)
-                resp = yield http_client.fetch(req)
-                resp_json = json.loads(resp.body.decode('utf8', 'replace'))
-                next_page = next_page_from_links(resp)
-                user_groups = set(entry["path"] for entry in resp_json)
-                # check if any of the organizations seen thus far are in whitelist
-                if len(self.gitlab_group_whitelist & user_groups) > 0:
-                    return True
-            return False
-
+        # Check if we are a member of each group in the whitelist
+        for group in map(url_escape, self.gitlab_group_whitelist):
+            url = "%s/groups/%s/members/%d" % (GITLAB_API, group, user_id)
+            req = HTTPRequest(url, method="GET", headers=headers)
+            resp = yield http_client.fetch(req, raise_error=False)
+            if resp.code == 200:
+                return True  # user _is_ in group
+        return False
 
 
 class LocalGitLabOAuthenticator(LocalAuthenticator, GitLabOAuthenticator):

programming_language: Python