| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -18,7 +18,7 @@ jobs: | |||
| 18 | 18 | runs-on: ubuntu-latest | |
| 19 | 19 | strategy: | |
| 20 | 20 | matrix: | |
| 21 | - python-version: [3.7, 3.7.5, 3.7.12, 3.8, 3.8.0, 3.8.11, 3.8, 3.9, 3.9.0, 3.9.7, "3.10"] | ||
| 21 | + python-version: [3.7, 3.8, 3.9, "3.10", "3.11"] | ||
| 22 | 22 | ||
| 23 | 23 | steps: | |
| 24 | 24 | - uses: actions/checkout@v3 | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,6 +2,18 @@ | |||
| 2 | 2 | Changelog | |
| 3 | 3 | ========= | |
| 4 | 4 | ||
| 5 | + 3.1.30 | ||
| 6 | + ====== | ||
| 7 | + | ||
| 8 | + - Make injections of command-invocations harder or impossible for clone and others. | ||
| 9 | + See https://github.com/gitpython-developers/GitPython/pull/1518 for details. | ||
| 10 | + Note that this might constitute a breaking change for some users, and if so please | ||
| 11 | + let us know and we add an opt-out to this. | ||
| 12 | + | ||
| 13 | + See the following for all changes. | ||
| 14 | + https://github.com/gitpython-developers/gitpython/milestone/60?closed=1 | ||
| 15 | + | ||
| 16 | + | ||
| 5 | 17 | 3.1.29 | |
| 6 | 18 | ====== | |
| 7 | 19 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -964,7 +964,7 @@ def fetch( | |||
| 964 | 964 | args = [refspec] | |
| 965 | 965 | ||
| 966 | 966 | proc = self.repo.git.fetch( | |
| 967 | - self, *args, as_process=True, with_stdout=False, universal_newlines=True, v=verbose, **kwargs | ||
| 967 | + "--", self, *args, as_process=True, with_stdout=False, universal_newlines=True, v=verbose, **kwargs | ||
| 968 | 968 | ) | |
| 969 | 969 | res = self._get_fetch_info_from_stderr(proc, progress, kill_after_timeout=kill_after_timeout) | |
| 970 | 970 | if hasattr(self.repo.odb, "update_cache"): | |
@@ -991,7 +991,7 @@ def pull( | |||
| 991 | 991 | self._assert_refspec() | |
| 992 | 992 | kwargs = add_progress(kwargs, self.repo.git, progress) | |
| 993 | 993 | proc = self.repo.git.pull( | |
| 994 | - self, refspec, with_stdout=False, as_process=True, universal_newlines=True, v=True, **kwargs | ||
| 994 | + "--", self, refspec, with_stdout=False, as_process=True, universal_newlines=True, v=True, **kwargs | ||
| 995 | 995 | ) | |
| 996 | 996 | res = self._get_fetch_info_from_stderr(proc, progress, kill_after_timeout=kill_after_timeout) | |
| 997 | 997 | if hasattr(self.repo.odb, "update_cache"): | |
@@ -1034,6 +1034,7 @@ def push( | |||
| 1034 | 1034 | be 0.""" | |
| 1035 | 1035 | kwargs = add_progress(kwargs, self.repo.git, progress) | |
| 1036 | 1036 | proc = self.repo.git.push( | |
| 1037 | + "--", | ||
| 1037 | 1038 | self, | |
| 1038 | 1039 | refspec, | |
| 1039 | 1040 | porcelain=True, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1169,6 +1169,7 @@ def _clone( | |||
| 1169 | 1169 | multi = shlex.split(" ".join(multi_options)) | |
| 1170 | 1170 | proc = git.clone( | |
| 1171 | 1171 | multi, | |
| 1172 | + "--", | ||
| 1172 | 1173 | Git.polish_url(str(url)), | |
| 1173 | 1174 | clone_path, | |
| 1174 | 1175 | with_extended_output=True, | |
@@ -1305,7 +1306,7 @@ def archive( | |||
| 1305 | 1306 | if not isinstance(path, (tuple, list)): | |
| 1306 | 1307 | path = [path] | |
| 1307 | 1308 | # end assure paths is list | |
| 1308 | - self.git.archive(treeish, *path, **kwargs) | ||
| 1309 | + self.git.archive("--", treeish, *path, **kwargs) | ||
| 1309 | 1310 | return self | |
| 1310 | 1311 | ||
| 1311 | 1312 | def has_separate_working_tree(self) -> bool: | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1180,3 +1180,29 @@ def test_do_not_strip_newline_in_stdout(self, rw_dir): | |||
| 1180 | 1180 | r.git.add(Git.polish_url(fp)) | |
| 1181 | 1181 | r.git.commit(message="init") | |
| 1182 | 1182 | self.assertEqual(r.git.show("HEAD:hello.txt", strip_newline_in_stdout=False), "hello\n") | |
| 1183 | + | ||
| 1184 | + @with_rw_repo("HEAD") | ||
| 1185 | + def test_clone_command_injection(self, rw_repo): | ||
| 1186 | + tmp_dir = pathlib.Path(tempfile.mkdtemp()) | ||
| 1187 | + unexpected_file = tmp_dir / "pwn" | ||
| 1188 | + assert not unexpected_file.exists() | ||
| 1189 | + | ||
| 1190 | + payload = f"--upload-pack=touch {unexpected_file}" | ||
| 1191 | + rw_repo.clone(payload) | ||
| 1192 | + | ||
| 1193 | + assert not unexpected_file.exists() | ||
| 1194 | + # A repo was cloned with the payload as name | ||
| 1195 | + assert pathlib.Path(payload).exists() | ||
| 1196 | + | ||
| 1197 | + @with_rw_repo("HEAD") | ||
| 1198 | + def test_clone_from_command_injection(self, rw_repo): | ||
| 1199 | + tmp_dir = pathlib.Path(tempfile.mkdtemp()) | ||
| 1200 | + temp_repo = Repo.init(tmp_dir / "repo") | ||
| 1201 | + unexpected_file = tmp_dir / "pwn" | ||
| 1202 | + | ||
| 1203 | + assert not unexpected_file.exists() | ||
| 1204 | + payload = f"--upload-pack=touch {unexpected_file}" | ||
| 1205 | + with self.assertRaises(GitCommandError): | ||
| 1206 | + rw_repo.clone_from(payload, temp_repo.common_dir) | ||
| 1207 | + | ||
| 1208 | + assert not unexpected_file.exists() | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments