Skip to content

Commit 250a6d1

Browse files
committed
Add a check to ensure the name resolves relative to the tmpdir.
Closes #4946
1 parent d8390fe commit 250a6d1

File tree

1 file changed

+16
-2
lines changed

1 file changed

+16
-2
lines changed

setuptools/package_index.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -810,12 +810,20 @@ def open_url(self, url, warning=None): # noqa: C901 # is too complex (12)
810810
@staticmethod
811811
def _resolve_download_filename(url, tmpdir):
812812
"""
813+
>>> import pathlib
813814
>>> du = PackageIndex._resolve_download_filename
814815
>>> root = getfixture('tmp_path')
815816
>>> url = 'https://files.pythonhosted.org/packages/a9/5a/0db.../setuptools-78.1.0.tar.gz'
816-
>>> import pathlib
817817
>>> str(pathlib.Path(du(url, root)).relative_to(root))
818818
'setuptools-78.1.0.tar.gz'
819+
820+
Ensures the target is always in tmpdir.
821+
822+
>>> url = 'https://anyhost/%2fhome%2fuser%2f.ssh%2fauthorized_keys'
823+
>>> du(url, root)
824+
Traceback (most recent call last):
825+
...
826+
ValueError: Invalid filename...
819827
"""
820828
name, _fragment = egg_info_for_url(url)
821829
if name:
@@ -827,7 +835,13 @@ def _resolve_download_filename(url, tmpdir):
827835
if name.endswith('.egg.zip'):
828836
name = name[:-4] # strip the extra .zip before download
829837

830-
return os.path.join(tmpdir, name)
838+
filename = os.path.join(tmpdir, name)
839+
840+
# ensure path resolves within the tmpdir
841+
if not filename.startswith(str(tmpdir)):
842+
raise ValueError(f"Invalid filename {filename}")
843+
844+
return filename
831845

832846
def _download_url(self, url, tmpdir):
833847
"""

0 commit comments

Comments
 (0)