Vulnerability: Code injection in nbgitpuller ### Impact

Due to an unsanitized input, visiting maliciously crafted links could result in arbitrary code execution in the user environment.

### Patches

0.10.2

### Workarounds

None, other than upgrade to 0.10.2 or downgrade to 0.8.x.


### For more information

If you have any questions or comments about this advisory:

* Open an issue in [nbgitpuller](https://github.com/jupyterhub/nbgitpuller/issues)
* Email our security team at [security@ipython.org](mailto:security@ipython.org)
Vulnerability ID: GHSA-mq5p-2mcr-m52j
CWE: CWE-94
Severity score: 0
Project: https://github.com/jupyterhub/nbgitpuller
Published: 2021-08-30
File: nbgitpuller/pull.py
Commit message: Merge pull request from GHSA-mq5p-2mcr-m52j

make positional args explicit
Commit author: Erik Sundell

Vulnerable version (before fix):
 def branch_exists(self, branch):         """         try:             heads = subprocess.run(                 ["git", "ls-remote", "--heads", self.git_url],                 capture_output=True,                 text=True,                 check=True             )             tags = subprocess.run(                 ["git", "ls-remote", "--tags", self.git_url],                 capture_output=True,                 text=True,                 check=True def resolve_default_branch(self):         """         try:             head_branch = subprocess.run(                 ["git", "ls-remote", "--symref", self.git_url, "HEAD"],                 capture_output=True,                 text=True,                 check=True def initialize_repo(self):         if self.depth and self.depth > 0:             clone_args.extend(['--depth', str(self.depth)])         clone_args.extend(['--branch', self.branch_name])         clone_args.extend([self.git_url, self.repo_dir])         yield from execute_cmd(clone_args)         logging.info('Repo {} initialized'.format(self.repo_dir)) 

Fixed version (after fix):
 def branch_exists(self, branch):         """         try:             heads = subprocess.run(                 ["git", "ls-remote", "--heads", "--", self.git_url],                 capture_output=True,                 text=True,                 check=True             )             tags = subprocess.run(                 ["git", "ls-remote", "--tags", "--", self.git_url],                 capture_output=True,                 text=True,                 check=True def resolve_default_branch(self):         """         try:             head_branch = subprocess.run(                 ["git", "ls-remote", "--symref", "--", self.git_url, "HEAD"],                 capture_output=True,                 text=True,                 check=True def initialize_repo(self):         if self.depth and self.depth > 0:             clone_args.extend(['--depth', str(self.depth)])         clone_args.extend(['--branch', self.branch_name])         clone_args.extend(["--", self.git_url, self.repo_dir])         yield from execute_cmd(clone_args)         logging.info('Repo {} initialized'.format(self.repo_dir)) 

Patch:
patch: @@ -88,13 +88,13 @@ def branch_exists(self, branch):
         """
         try:
             heads = subprocess.run(
-                ["git", "ls-remote", "--heads", self.git_url],
+                ["git", "ls-remote", "--heads", "--", self.git_url],
                 capture_output=True,
                 text=True,
                 check=True
             )
             tags = subprocess.run(
-                ["git", "ls-remote", "--tags", self.git_url],
+                ["git", "ls-remote", "--tags", "--", self.git_url],
                 capture_output=True,
                 text=True,
                 check=True
@@ -118,7 +118,7 @@ def resolve_default_branch(self):
         """
         try:
             head_branch = subprocess.run(
-                ["git", "ls-remote", "--symref", self.git_url, "HEAD"],
+                ["git", "ls-remote", "--symref", "--", self.git_url, "HEAD"],
                 capture_output=True,
                 text=True,
                 check=True
@@ -154,7 +154,7 @@ def initialize_repo(self):
         if self.depth and self.depth > 0:
             clone_args.extend(['--depth', str(self.depth)])
         clone_args.extend(['--branch', self.branch_name])
-        clone_args.extend([self.git_url, self.repo_dir])
+        clone_args.extend(["--", self.git_url, self.repo_dir])
         yield from execute_cmd(clone_args)
         logging.info('Repo {} initialized'.format(self.repo_dir))
path: nbgitpuller/pull.py