]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-146121: `pkgutil.get_data()` reject invalid resource arguments (#146122)
authorStan Ulbrych <89152624+StanFromIreland@users.noreply.github.com>
Wed, 18 Mar 2026 17:31:01 +0000 (17:31 +0000)
committerGitHub <noreply@github.com>
Wed, 18 Mar 2026 17:31:01 +0000 (17:31 +0000)
Lib/pkgutil.py
Lib/test/test_pkgutil.py
Misc/NEWS.d/next/Security/2026-03-16-18-07-00.gh-issue-146121.vRbdro.rst [new file with mode: 0644]

index 8772a66791a3c9aced4fa96e23ea79c1eda17f5d..c3109a3a4cd414d5a7d03a27a19a7d1161152d0a 100644 (file)
@@ -393,6 +393,9 @@ def get_data(package, resource):
     # signature - an os.path format "filename" starting with the dirname of
     # the package's __file__
     parts = resource.split('/')
+    if os.path.isabs(resource) or '..' in parts:
+        raise ValueError("resource must be a relative path with no "
+                         "parent directory components")
     parts.insert(0, os.path.dirname(mod.__file__))
     resource_name = os.path.join(*parts)
     return loader.get_data(resource_name)
index d4faaaeca0045726ce2c49e61497a6a7640a8115..948afb8c18cf67e671eea16d43bac77e825b881d 100644 (file)
@@ -61,6 +61,25 @@ class PkgutilTests(unittest.TestCase):
 
         del sys.modules[pkg]
 
+    def test_getdata_path_traversal(self):
+        pkg = 'test_getdata_traversal'
+
+        # Make a package with some resources
+        package_dir = os.path.join(self.dirname, pkg)
+        os.mkdir(package_dir)
+        # Empty init.py
+        f = open(os.path.join(package_dir, '__init__.py'), "wb")
+        f.close()
+
+        with self.assertRaises(ValueError):
+            pkgutil.get_data(pkg, '../../../etc/passwd')
+        with self.assertRaises(ValueError):
+            pkgutil.get_data(pkg, 'sub/../../../etc/passwd')
+        with self.assertRaises(ValueError):
+            pkgutil.get_data(pkg, os.path.abspath('/etc/passwd'))
+
+        del sys.modules[pkg]
+
     def test_getdata_zipfile(self):
         zip = 'test_getdata_zipfile.zip'
         pkg = 'test_getdata_zipfile'
diff --git a/Misc/NEWS.d/next/Security/2026-03-16-18-07-00.gh-issue-146121.vRbdro.rst b/Misc/NEWS.d/next/Security/2026-03-16-18-07-00.gh-issue-146121.vRbdro.rst
new file mode 100644 (file)
index 0000000..c0ee07d
--- /dev/null
@@ -0,0 +1,3 @@
+:func:`pkgutil.get_data` now raises rejects *resource* arguments containing the
+parent directory components or that is an absolute path.
+This addresses :cve:`2026-3479`.