diff options
author | Jason R. Coombs <jaraco@jaraco.com> | 2019-01-27 13:13:57 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-01-27 13:13:57 -0500 |
commit | 0425790c7d2d60ebd0e576796d07288a43fcaf0c (patch) | |
tree | 41c3e4caeb4d3e452bbadcf771a3056ab9f561c1 /pkg_resources/__init__.py | |
parent | 97e8ad4f5ff7793729e9c8be38e0901e3ad8d09e (diff) | |
parent | 6636302f735d94fe91b83469f1610e4112a91838 (diff) | |
download | external_python_setuptools-0425790c7d2d60ebd0e576796d07288a43fcaf0c.tar.gz external_python_setuptools-0425790c7d2d60ebd0e576796d07288a43fcaf0c.tar.bz2 external_python_setuptools-0425790c7d2d60ebd0e576796d07288a43fcaf0c.zip |
Merge pull request #1640 from pypa/bugfix/1635-disallow-parent-paths
Disallow parent path traversal in resource paths, part 1 (deprecation)
Diffstat (limited to 'pkg_resources/__init__.py')
-rw-r--r-- | pkg_resources/__init__.py | 67 |
1 files changed, 66 insertions, 1 deletions
diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 6ca68daa..dcfa1d08 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -39,6 +39,8 @@ import tempfile import textwrap import itertools import inspect +import ntpath +import posixpath from pkgutil import get_importer try: @@ -1466,10 +1468,73 @@ class NullProvider: ) def _fn(self, base, resource_name): + self._validate_resource_path(resource_name) if resource_name: return os.path.join(base, *resource_name.split('/')) return base + @staticmethod + def _validate_resource_path(path): + """ + Validate the resource paths according to the docs. + https://setuptools.readthedocs.io/en/latest/pkg_resources.html#basic-resource-access + + >>> warned = getfixture('recwarn') + >>> warnings.simplefilter('always') + >>> vrp = NullProvider._validate_resource_path + >>> vrp('foo/bar.txt') + >>> bool(warned) + False + >>> vrp('../foo/bar.txt') + >>> bool(warned) + True + >>> warned.clear() + >>> vrp('/foo/bar.txt') + >>> bool(warned) + True + >>> vrp('foo/../../bar.txt') + >>> bool(warned) + True + >>> warned.clear() + >>> vrp('foo/f../bar.txt') + >>> bool(warned) + False + + Windows path separators are straight-up disallowed. + >>> vrp(r'\\foo/bar.txt') + Traceback (most recent call last): + ... + ValueError: Use of .. or absolute path in a resource path \ +is not allowed. + + >>> vrp(r'C:\\foo/bar.txt') + Traceback (most recent call last): + ... + ValueError: Use of .. or absolute path in a resource path \ +is not allowed. + """ + invalid = ( + os.path.pardir in path.split(posixpath.sep) or + posixpath.isabs(path) or + ntpath.isabs(path) + ) + if not invalid: + return + + msg = "Use of .. or absolute path in a resource path is not allowed." + + # Aggressively disallow Windows absolute paths + if ntpath.isabs(path) and not posixpath.isabs(path): + raise ValueError(msg) + + # for compatibility, warn; in future + # raise ValueError(msg) + warnings.warn( + msg[:-1] + " and will raise exceptions in a future release.", + DeprecationWarning, + stacklevel=4, + ) + def _get(self, path): if hasattr(self.loader, 'get_data'): return self.loader.get_data(path) @@ -1888,7 +1953,7 @@ def find_eggs_in_zip(importer, path_item, only=False): if only: # don't yield nested distros return - for subitem in metadata.resource_listdir('/'): + for subitem in metadata.resource_listdir(''): if _is_egg_path(subitem): subpath = os.path.join(path_item, subitem) dists = find_eggs_in_zip(zipimport.zipimporter(subpath), subpath) |