|
|
175766 |
From 843735d9dc129eb34f16c4c08576ac5f742971f6 Mon Sep 17 00:00:00 2001
|
|
|
175766 |
From: Lumir Balhar <lbalhar@redhat.com>
|
|
|
175766 |
Date: Tue, 17 May 2022 12:44:01 +0200
|
|
|
175766 |
Subject: [PATCH] CVE-2019-20916
|
|
|
175766 |
|
|
|
175766 |
---
|
|
|
175766 |
download.py | 31 +++++++++++++++++++++++++-----
|
|
|
175766 |
1 file changed, 26 insertions(+), 5 deletions(-)
|
|
|
175766 |
|
|
|
175766 |
diff --git a/download.py b/download.py
|
|
|
175766 |
index 54d3131..e49130b 100644
|
|
|
175766 |
--- a/download.py
|
|
|
175766 |
+++ b/download.py
|
|
|
175766 |
@@ -54,7 +54,8 @@ __all__ = ['get_file_content',
|
|
|
175766 |
'is_url', 'url_to_path', 'path_to_url',
|
|
|
175766 |
'is_archive_file', 'unpack_vcs_link',
|
|
|
175766 |
'unpack_file_url', 'is_vcs_url', 'is_file_url',
|
|
|
175766 |
- 'unpack_http_url', 'unpack_url']
|
|
|
175766 |
+ 'unpack_http_url', 'unpack_url',
|
|
|
175766 |
+ 'parse_content_disposition', 'sanitize_content_filename']
|
|
|
175766 |
|
|
|
175766 |
|
|
|
175766 |
logger = logging.getLogger(__name__)
|
|
|
175766 |
@@ -824,6 +825,29 @@ def unpack_url(link, location, download_dir=None,
|
|
|
175766 |
write_delete_marker_file(location)
|
|
|
175766 |
|
|
|
175766 |
|
|
|
175766 |
+def sanitize_content_filename(filename):
|
|
|
175766 |
+ # type: (str) -> str
|
|
|
175766 |
+ """
|
|
|
175766 |
+ Sanitize the "filename" value from a Content-Disposition header.
|
|
|
175766 |
+ """
|
|
|
175766 |
+ return os.path.basename(filename)
|
|
|
175766 |
+
|
|
|
175766 |
+
|
|
|
175766 |
+def parse_content_disposition(content_disposition, default_filename):
|
|
|
175766 |
+ # type: (str, str) -> str
|
|
|
175766 |
+ """
|
|
|
175766 |
+ Parse the "filename" value from a Content-Disposition header, and
|
|
|
175766 |
+ return the default filename if the result is empty.
|
|
|
175766 |
+ """
|
|
|
175766 |
+ _type, params = cgi.parse_header(content_disposition)
|
|
|
175766 |
+ filename = params.get('filename')
|
|
|
175766 |
+ if filename:
|
|
|
175766 |
+ # We need to sanitize the filename to prevent directory traversal
|
|
|
175766 |
+ # in case the filename contains ".." path parts.
|
|
|
175766 |
+ filename = sanitize_content_filename(filename)
|
|
|
175766 |
+ return filename or default_filename
|
|
|
175766 |
+
|
|
|
175766 |
+
|
|
|
175766 |
def _download_http_url(link, session, temp_dir, hashes):
|
|
|
175766 |
"""Download link url into temp_dir using provided session"""
|
|
|
175766 |
target_url = link.url.split('#', 1)[0]
|
|
|
175766 |
@@ -864,10 +888,7 @@ def _download_http_url(link, session, temp_dir, hashes):
|
|
|
175766 |
# Have a look at the Content-Disposition header for a better guess
|
|
|
175766 |
content_disposition = resp.headers.get('content-disposition')
|
|
|
175766 |
if content_disposition:
|
|
|
175766 |
- type, params = cgi.parse_header(content_disposition)
|
|
|
175766 |
- # We use ``or`` here because we don't want to use an "empty" value
|
|
|
175766 |
- # from the filename param.
|
|
|
175766 |
- filename = params.get('filename') or filename
|
|
|
175766 |
+ filename = parse_content_disposition(content_disposition, filename)
|
|
|
175766 |
ext = splitext(filename)[1]
|
|
|
175766 |
if not ext:
|
|
|
175766 |
ext = mimetypes.guess_extension(content_type)
|
|
|
175766 |
--
|
|
|
175766 |
2.35.3
|
|
|
175766 |
|