Critical severity9.3NVD Advisory· Published Mar 31, 2015· Updated May 6, 2026
CVE-2014-9706
CVE-2014-9706
Description
The build_index_from_tree function in index.py in Dulwich before 0.9.9 allows remote attackers to execute arbitrary code via a commit with a directory path starting with .git/, which is not properly handled when checking out a working tree.
Affected products
2- cpe:2.3:o:debian:debian_linux:7.0:*:*:*:*:*:*:*
Patches
1091638be3c89By default refuse to create index entries with a path starting with .git/.
3 files changed · +53 −2
dulwich/index.py+11 −1 modified@@ -431,8 +431,14 @@ def build_file_from_blob(blob, mode, target_path, honor_filemode=True): os.chmod(target_path, mode) +def validate_path_default(path): + """Default path validator that just checks for .git/.""" + return not path.startswith(".git/") + + def build_index_from_tree(prefix, index_path, object_store, tree_id, - honor_filemode=True): + honor_filemode=True, + validate_path=validate_path_default): """Generate and materialize index from a tree :param tree_id: Tree to materialize @@ -441,6 +447,8 @@ def build_index_from_tree(prefix, index_path, object_store, tree_id, :param object_store: Non-empty object store holding tree contents :param honor_filemode: An optional flag to honor core.filemode setting in config file, default is core.filemode=True, change executable bit + :param validate_path: Function to validate paths to check out; + default just refuses filenames starting with .git/. :note:: existing index is wiped and contents are not merged in a working dir. Suiteable only for fresh clones. @@ -449,6 +457,8 @@ def build_index_from_tree(prefix, index_path, object_store, tree_id, index = Index(index_path) for entry in object_store.iter_tree_contents(tree_id): + if not validate_path(entry.path): + continue full_path = os.path.join(prefix, entry.path) if not os.path.exists(os.path.dirname(full_path)):
dulwich/tests/test_index.py+37 −1 modified@@ -50,7 +50,6 @@ from dulwich.tests import TestCase from dulwich.tests.utils import skipIfPY3 - @skipIfPY3 class IndexTestCase(TestCase): @@ -281,6 +280,43 @@ def test_empty(self): # Verify no files self.assertEqual(['.git'], os.listdir(repo.path)) + def test_git_dir(self): + if os.name != 'posix': + self.skipTest("test depends on POSIX shell") + + repo_dir = tempfile.mkdtemp() + repo = Repo.init(repo_dir) + self.addCleanup(shutil.rmtree, repo_dir) + + # Populate repo + filea = Blob.from_string('file a') + filee = Blob.from_string('d') + + tree = Tree() + tree['.git/a'] = (stat.S_IFREG | 0o644, filea.id) + tree['c/e'] = (stat.S_IFREG | 0o644, filee.id) + + repo.object_store.add_objects([(o, None) + for o in [filea, filee, tree]]) + + build_index_from_tree(repo.path, repo.index_path(), + repo.object_store, tree.id) + + # Verify index entries + index = repo.open_index() + self.assertEqual(len(index), 1) + + # filea + apath = os.path.join(repo.path, '.git', 'a') + self.assertFalse(os.path.exists(apath)) + + # filee + epath = os.path.join(repo.path, 'c', 'e') + self.assertTrue(os.path.exists(epath)) + self.assertReasonableIndexEntry(index['c/e'], + stat.S_IFREG | 0o644, 1, filee.id) + self.assertFileContents(epath, 'd') + def test_nonempty(self): if os.name != 'posix': self.skipTest("test depends on POSIX shell")
NEWS+5 −0 modified@@ -1,5 +1,10 @@ 0.9.9 UNRELEASED + BUG FIXES + + * In dulwich.index.build_index_from_tree, by default + refuse to create entries that start with .git/. + 0.9.8 2014-11-30 BUG FIXES
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
10- www.openwall.com/lists/oss-security/2015/03/21/1nvdExploit
- lists.launchpad.net/dulwich-users/msg00827.htmlnvdExploit
- github.com/advisories/GHSA-4j5j-58j7-6c3wghsaADVISORY
- lists.fedoraproject.org/pipermail/package-announce/2015-April/154523.htmlnvd
- lists.fedoraproject.org/pipermail/package-announce/2015-April/154551.htmlnvd
- www.debian.org/security/2015/dsa-3206nvd
- www.openwall.com/lists/oss-security/2015/03/22/26nvd
- github.com/jelmer/dulwich/commit/091638be3c89f46f42c3b1d57dc1504af5729176ghsa
- github.com/pypa/advisory-database/tree/main/vulns/dulwich/PYSEC-2015-34.yamlghsa
- nvd.nist.gov/vuln/detail/CVE-2014-9706ghsa
News mentions
0No linked articles in our index yet.