CVE-2020-15110 (published 2020-07-17T21:15Z)

In jupyterhub-kubespawner before 0.12, certain usernames will be able to craft particular server names which will grant them access to the default server of other users who have matching usernames. This has been fixed in 0.12.

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

Weakness information:
cwe_id: CWE-863
cwe_name: Incorrect Authorization
description: The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check. This allows attackers to bypass intended access restrictions.
extended_description: 
            Assuming a user with a given identity, authorization is the process of determining whether that user can access a given resource, based on the user's privileges and any permissions or other access-control specifications that apply to the resource.
            When access control checks are incorrectly applied, users are able to access data or perform actions that they should not be allowed to perform. This can lead to a wide range of problems, including information exposures, denial of service, and arbitrary code execution.
         
         

Fix information:
repo_url: https://github.com/jupyterhub/kubespawner
commit_details: repo_url: https://github.com/jupyterhub/kubespawner
author: Min RK
author_date: 2020-07-03 09:48:42+02:00
msg: move delimiter to pvc/pod name templates

and note version change
repository: repo_url: https://github.com/jupyterhub/kubespawner
repo_name: jupyterhub/kubespawner
description: Kubernetes spawner for JupyterHub
repo_language: Python
owner: jupyterhub
file_changes: filename: spawner.py
change_type: ModificationType.MODIFY
diff: @@ -307,16 +307,25 @@ class KubeSpawner(Spawner):
     )
 
     pod_name_template = Unicode(
-        'jupyter-{username}{servername}',
+        'jupyter-{username}--{servername}',
         config=True,
         help="""
         Template to use to form the name of user's pods.
 
-        `{username}` is expanded to the escaped, dns-label safe username.
+        `{username}` is expanded to the escaped, dns-label-safe username.
+        `{servername}` is expanded to the escaped, dns-label-safe server name, if any.
+
+        Trailing `-` characters are stripped for safe handling of empty server names (user default servers).
 
         This must be unique within the namespace the pods are being spawned
         in, so if you are running multiple jupyterhubs spawning in the
         same namespace, consider setting this to be something more unique.
+
+        .. versionchanged:: 0.12
+            `--` delimiter added to the template,
+            where it was implicitly added to the `servername` field before.
+            Additionally, `username--servername` delimiter was `-` instead of `--`,
+            allowing collisions in certain circumstances.
         """
     )
 
@@ -332,16 +341,25 @@ class KubeSpawner(Spawner):
     )
 
     pvc_name_template = Unicode(
-        'claim-{username}{servername}',
+        'claim-{username}--{servername}',
         config=True,
         help="""
         Template to use to form the name of user's pvc.
 
         `{username}` is expanded to the escaped, dns-label safe username.
+        `{servername}` is expanded to the escaped, dns-label-safe server name, if any.
+
+        Trailing `-` characters are stripped for safe handling of empty server names (user default servers).
 
         This must be unique within the namespace the pvc are being spawned
         in, so if you are running multiple jupyterhubs spawning in the
         same namespace, consider setting this to be something more unique.
+
+        .. versionchanged:: 0.12
+            `--` delimiter added to the template,
+            where it was implicitly added to the `servername` field before.
+            Additionally, `username--servername` delimiter was `-` instead of `--`,
+            allowing collisions in certain circumstances.
         """
     )
 
@@ -1313,28 +1331,22 @@ class KubeSpawner(Spawner):
         # Note: '-' is not in safe_chars, as it is being used as escape character
         safe_chars = set(string.ascii_lowercase + string.digits)
 
-        # Set servername based on whether named-server initialised
-        if self.name:
-            # use two -- to ensure no collision possibilities
-            # are created by an ambiguous boundary between username and
-            # servername.
-            # -- cannot occur in a string where - is the escape char.
-            servername = '--{}'.format(self.name)
-            safe_servername = '--{}'.format(escapism.escape(self.name, safe=safe_chars, escape_char='-').lower())
-        else:
-            servername = ''
-            safe_servername = ''
+        raw_servername = self.name or ''
+        safe_servername = escapism.escape(raw_servername, safe=safe_chars, escape_char='-').lower()
 
         legacy_escaped_username = ''.join([s if s in safe_chars else '-' for s in self.user.name.lower()])
         safe_username = escapism.escape(self.user.name, safe=safe_chars, escape_char='-').lower()
-        return template.format(
+        rendered = template.format(
             userid=self.user.id,
             username=safe_username,
             unescaped_username=self.user.name,
             legacy_escape_username=legacy_escaped_username,
             servername=safe_servername,
-            unescaped_servername=servername,
+            unescaped_servername=raw_servername,
         )
+        # strip trailing - delimiter in case of empty servername.
+        # k8s object names cannot have trailing -
+        return rendered.rstrip("-")
 
     def _expand_all(self, src):
         if isinstance(src, list):

programming_language: Python