From a2cb536b911b4936ab02cc2e5442a046000934ea Mon Sep 17 00:00:00 2001 From: Chen Qi Date: Thu, 22 Apr 2021 14:01:01 +0800 Subject: [PATCH 1/5] python3-django: upgrade to 2.2.20 2.2.x is LTS, so upgrade to latest release 2.2.20. This upgrade fixes several CVEs such as CVE-2021-3281. Also, CVE-2021-28658.patch is dropped as it's already in 2.2.20. Signed-off-by: Chen Qi Signed-off-by: Khem Raj Signed-off-by: Trevor Gamblin --- .../CVE-2021-28658.patch | 289 ------------------ .../python/python3-django_2.2.16.bb | 11 - .../python/python3-django_2.2.20.bb | 9 + 3 files changed, 9 insertions(+), 300 deletions(-) delete mode 100644 meta-python/recipes-devtools/python/python3-django-2.2.16/CVE-2021-28658.patch delete mode 100644 meta-python/recipes-devtools/python/python3-django_2.2.16.bb create mode 100644 meta-python/recipes-devtools/python/python3-django_2.2.20.bb diff --git a/meta-python/recipes-devtools/python/python3-django-2.2.16/CVE-2021-28658.patch b/meta-python/recipes-devtools/python/python3-django-2.2.16/CVE-2021-28658.patch deleted file mode 100644 index 325aa004200..00000000000 --- a/meta-python/recipes-devtools/python/python3-django-2.2.16/CVE-2021-28658.patch +++ /dev/null @@ -1,289 +0,0 @@ -From 4036d62bda0e9e9f6172943794b744a454ca49c2 Mon Sep 17 00:00:00 2001 -From: Mariusz Felisiak -Date: Tue, 16 Mar 2021 10:19:00 +0100 -Subject: [PATCH] Fixed CVE-2021-28658 -- Fixed potential directory-traversal - via uploaded files. - -Thanks Claude Paroz for the initial patch. -Thanks Dennis Brinkrolf for the report. - -Backport of d4d800ca1addc4141e03c5440a849bb64d1582cd from main. - -Upstream-Status: Backport -CVE: CVE-2021-28658 - -Reference to upstream patch: -[https://github.com/django/django/commit/4036d62bda0e9e9f6172943794b744a454ca49c2] - -[SG: Adapted stable/2.2.x patch for 2.2.16] -Signed-off-by: Stefan Ghinea ---- - django/http/multipartparser.py | 13 ++++-- - docs/releases/2.2.16.txt | 12 +++++ - tests/file_uploads/tests.py | 72 ++++++++++++++++++++++------- - tests/file_uploads/uploadhandler.py | 31 +++++++++++++ - tests/file_uploads/urls.py | 1 + - tests/file_uploads/views.py | 12 ++++- - 6 files changed, 120 insertions(+), 21 deletions(-) - -diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py -index f6f12ca..5a9cca8 100644 ---- a/django/http/multipartparser.py -+++ b/django/http/multipartparser.py -@@ -7,6 +7,7 @@ file upload handlers for processing. - import base64 - import binascii - import cgi -+import os - from urllib.parse import unquote - - from django.conf import settings -@@ -205,7 +206,7 @@ class MultiPartParser: - file_name = disposition.get('filename') - if file_name: - file_name = force_text(file_name, encoding, errors='replace') -- file_name = self.IE_sanitize(unescape_entities(file_name)) -+ file_name = self.sanitize_file_name(file_name) - if not file_name: - continue - -@@ -293,9 +294,13 @@ class MultiPartParser: - self._files.appendlist(force_text(old_field_name, self._encoding, errors='replace'), file_obj) - break - -- def IE_sanitize(self, filename): -- """Cleanup filename from Internet Explorer full paths.""" -- return filename and filename[filename.rfind("\\") + 1:].strip() -+ def sanitize_file_name(self, file_name): -+ file_name = unescape_entities(file_name) -+ # Cleanup Windows-style path separators. -+ file_name = file_name[file_name.rfind('\\') + 1:].strip() -+ return os.path.basename(file_name) -+ -+ IE_sanitize = sanitize_file_name - - def _close_files(self): - # Free up all file handles. -diff --git a/docs/releases/2.2.16.txt b/docs/releases/2.2.16.txt -index 31231fb..4b7021b 100644 ---- a/docs/releases/2.2.16.txt -+++ b/docs/releases/2.2.16.txt -@@ -2,6 +2,18 @@ - Django 2.2.16 release notes - =========================== - -+*April 6, 2021* -+ -+Backported from Django 2.2.20 a fix for a security issue. -+ -+CVE-2021-28658: Potential directory-traversal via uploaded files -+================================================================ -+ -+``MultiPartParser`` allowed directory-traversal via uploaded files with -+suitably crafted file names. -+ -+Built-in upload handlers were not affected by this vulnerability. -+ - *September 1, 2020* - - Django 2.2.16 fixes two security issues and two data loss bugs in 2.2.15. -diff --git a/tests/file_uploads/tests.py b/tests/file_uploads/tests.py -index ea4976d..2a08d1b 100644 ---- a/tests/file_uploads/tests.py -+++ b/tests/file_uploads/tests.py -@@ -22,6 +22,21 @@ UNICODE_FILENAME = 'test-0123456789_中文_Orléans.jpg' - MEDIA_ROOT = sys_tempfile.mkdtemp() - UPLOAD_TO = os.path.join(MEDIA_ROOT, 'test_upload') - -+CANDIDATE_TRAVERSAL_FILE_NAMES = [ -+ '/tmp/hax0rd.txt', # Absolute path, *nix-style. -+ 'C:\\Windows\\hax0rd.txt', # Absolute path, win-style. -+ 'C:/Windows/hax0rd.txt', # Absolute path, broken-style. -+ '\\tmp\\hax0rd.txt', # Absolute path, broken in a different way. -+ '/tmp\\hax0rd.txt', # Absolute path, broken by mixing. -+ 'subdir/hax0rd.txt', # Descendant path, *nix-style. -+ 'subdir\\hax0rd.txt', # Descendant path, win-style. -+ 'sub/dir\\hax0rd.txt', # Descendant path, mixed. -+ '../../hax0rd.txt', # Relative path, *nix-style. -+ '..\\..\\hax0rd.txt', # Relative path, win-style. -+ '../..\\hax0rd.txt', # Relative path, mixed. -+ '../hax0rd.txt', # HTML entities. -+] -+ - - @override_settings(MEDIA_ROOT=MEDIA_ROOT, ROOT_URLCONF='file_uploads.urls', MIDDLEWARE=[]) - class FileUploadTests(TestCase): -@@ -205,22 +220,8 @@ class FileUploadTests(TestCase): - # a malicious payload with an invalid file name (containing os.sep or - # os.pardir). This similar to what an attacker would need to do when - # trying such an attack. -- scary_file_names = [ -- "/tmp/hax0rd.txt", # Absolute path, *nix-style. -- "C:\\Windows\\hax0rd.txt", # Absolute path, win-style. -- "C:/Windows/hax0rd.txt", # Absolute path, broken-style. -- "\\tmp\\hax0rd.txt", # Absolute path, broken in a different way. -- "/tmp\\hax0rd.txt", # Absolute path, broken by mixing. -- "subdir/hax0rd.txt", # Descendant path, *nix-style. -- "subdir\\hax0rd.txt", # Descendant path, win-style. -- "sub/dir\\hax0rd.txt", # Descendant path, mixed. -- "../../hax0rd.txt", # Relative path, *nix-style. -- "..\\..\\hax0rd.txt", # Relative path, win-style. -- "../..\\hax0rd.txt" # Relative path, mixed. -- ] -- - payload = client.FakePayload() -- for i, name in enumerate(scary_file_names): -+ for i, name in enumerate(CANDIDATE_TRAVERSAL_FILE_NAMES): - payload.write('\r\n'.join([ - '--' + client.BOUNDARY, - 'Content-Disposition: form-data; name="file%s"; filename="%s"' % (i, name), -@@ -240,7 +241,7 @@ class FileUploadTests(TestCase): - response = self.client.request(**r) - # The filenames should have been sanitized by the time it got to the view. - received = response.json() -- for i, name in enumerate(scary_file_names): -+ for i, name in enumerate(CANDIDATE_TRAVERSAL_FILE_NAMES): - got = received["file%s" % i] - self.assertEqual(got, "hax0rd.txt") - -@@ -518,6 +519,36 @@ class FileUploadTests(TestCase): - # shouldn't differ. - self.assertEqual(os.path.basename(obj.testfile.path), 'MiXeD_cAsE.txt') - -+ def test_filename_traversal_upload(self): -+ os.makedirs(UPLOAD_TO, exist_ok=True) -+ self.addCleanup(shutil.rmtree, MEDIA_ROOT) -+ file_name = '../test.txt', -+ payload = client.FakePayload() -+ payload.write( -+ '\r\n'.join([ -+ '--' + client.BOUNDARY, -+ 'Content-Disposition: form-data; name="my_file"; ' -+ 'filename="%s";' % file_name, -+ 'Content-Type: text/plain', -+ '', -+ 'file contents.\r\n', -+ '\r\n--' + client.BOUNDARY + '--\r\n', -+ ]), -+ ) -+ r = { -+ 'CONTENT_LENGTH': len(payload), -+ 'CONTENT_TYPE': client.MULTIPART_CONTENT, -+ 'PATH_INFO': '/upload_traversal/', -+ 'REQUEST_METHOD': 'POST', -+ 'wsgi.input': payload, -+ } -+ response = self.client.request(**r) -+ result = response.json() -+ self.assertEqual(response.status_code, 200) -+ self.assertEqual(result['file_name'], 'test.txt') -+ self.assertIs(os.path.exists(os.path.join(MEDIA_ROOT, 'test.txt')), False) -+ self.assertIs(os.path.exists(os.path.join(UPLOAD_TO, 'test.txt')), True) -+ - - @override_settings(MEDIA_ROOT=MEDIA_ROOT) - class DirectoryCreationTests(SimpleTestCase): -@@ -591,6 +622,15 @@ class MultiParserTests(SimpleTestCase): - }, StringIO('x'), [], 'utf-8') - self.assertEqual(multipart_parser._content_length, 0) - -+ def test_sanitize_file_name(self): -+ parser = MultiPartParser({ -+ 'CONTENT_TYPE': 'multipart/form-data; boundary=_foo', -+ 'CONTENT_LENGTH': '1' -+ }, StringIO('x'), [], 'utf-8') -+ for file_name in CANDIDATE_TRAVERSAL_FILE_NAMES: -+ with self.subTest(file_name=file_name): -+ self.assertEqual(parser.sanitize_file_name(file_name), 'hax0rd.txt') -+ - def test_rfc2231_parsing(self): - test_data = ( - (b"Content-Type: application/x-stuff; title*=us-ascii'en-us'This%20is%20%2A%2A%2Afun%2A%2A%2A", -diff --git a/tests/file_uploads/uploadhandler.py b/tests/file_uploads/uploadhandler.py -index 7c6199f..65d70c6 100644 ---- a/tests/file_uploads/uploadhandler.py -+++ b/tests/file_uploads/uploadhandler.py -@@ -1,6 +1,8 @@ - """ - Upload handlers to test the upload API. - """ -+import os -+from tempfile import NamedTemporaryFile - - from django.core.files.uploadhandler import FileUploadHandler, StopUpload - -@@ -35,3 +37,32 @@ class ErroringUploadHandler(FileUploadHandler): - """A handler that raises an exception.""" - def receive_data_chunk(self, raw_data, start): - raise CustomUploadError("Oops!") -+ -+ -+class TraversalUploadHandler(FileUploadHandler): -+ """A handler with potential directory-traversal vulnerability.""" -+ def __init__(self, request=None): -+ from .views import UPLOAD_TO -+ -+ super().__init__(request) -+ self.upload_dir = UPLOAD_TO -+ -+ def file_complete(self, file_size): -+ self.file.seek(0) -+ self.file.size = file_size -+ with open(os.path.join(self.upload_dir, self.file_name), 'wb') as fp: -+ fp.write(self.file.read()) -+ return self.file -+ -+ def new_file( -+ self, field_name, file_name, content_type, content_length, charset=None, -+ content_type_extra=None, -+ ): -+ super().new_file( -+ file_name, file_name, content_length, content_length, charset, -+ content_type_extra, -+ ) -+ self.file = NamedTemporaryFile(suffix='.upload', dir=self.upload_dir) -+ -+ def receive_data_chunk(self, raw_data, start): -+ self.file.write(raw_data) -diff --git a/tests/file_uploads/urls.py b/tests/file_uploads/urls.py -index 3e7985d..eaac1da 100644 ---- a/tests/file_uploads/urls.py -+++ b/tests/file_uploads/urls.py -@@ -4,6 +4,7 @@ from . import views - - urlpatterns = [ - path('upload/', views.file_upload_view), -+ path('upload_traversal/', views.file_upload_traversal_view), - path('verify/', views.file_upload_view_verify), - path('unicode_name/', views.file_upload_unicode_name), - path('echo/', views.file_upload_echo), -diff --git a/tests/file_uploads/views.py b/tests/file_uploads/views.py -index d4947e4..137c6f3 100644 ---- a/tests/file_uploads/views.py -+++ b/tests/file_uploads/views.py -@@ -6,7 +6,9 @@ from django.http import HttpResponse, HttpResponseServerError, JsonResponse - - from .models import FileModel - from .tests import UNICODE_FILENAME, UPLOAD_TO --from .uploadhandler import ErroringUploadHandler, QuotaUploadHandler -+from .uploadhandler import ( -+ ErroringUploadHandler, QuotaUploadHandler, TraversalUploadHandler, -+) - - - def file_upload_view(request): -@@ -158,3 +160,11 @@ def file_upload_fd_closing(request, access): - if access == 't': - request.FILES # Trigger file parsing. - return HttpResponse('') -+ -+ -+def file_upload_traversal_view(request): -+ request.upload_handlers.insert(0, TraversalUploadHandler()) -+ request.FILES # Trigger file parsing. -+ return JsonResponse( -+ {'file_name': request.upload_handlers[0].file_name}, -+ ) --- -2.17.1 - diff --git a/meta-python/recipes-devtools/python/python3-django_2.2.16.bb b/meta-python/recipes-devtools/python/python3-django_2.2.16.bb deleted file mode 100644 index eb626e8d3f0..00000000000 --- a/meta-python/recipes-devtools/python/python3-django_2.2.16.bb +++ /dev/null @@ -1,11 +0,0 @@ -require python-django.inc -inherit setuptools3 - -SRC_URI[md5sum] = "93faf5bbd54a19ea49f4932a813b9758" -SRC_URI[sha256sum] = "62cf45e5ee425c52e411c0742e641a6588b7e8af0d2c274a27940931b2786594" - -RDEPENDS_${PN} += "\ - ${PYTHON_PN}-sqlparse \ -" -SRC_URI += "file://CVE-2021-28658.patch \ -" diff --git a/meta-python/recipes-devtools/python/python3-django_2.2.20.bb b/meta-python/recipes-devtools/python/python3-django_2.2.20.bb new file mode 100644 index 00000000000..905d022a4f4 --- /dev/null +++ b/meta-python/recipes-devtools/python/python3-django_2.2.20.bb @@ -0,0 +1,9 @@ +require python-django.inc +inherit setuptools3 + +SRC_URI[md5sum] = "947060d96ccc0a05e8049d839e541b25" +SRC_URI[sha256sum] = "2569f9dc5f8e458a5e988b03d6b7a02bda59b006d6782f4ea0fd590ed7336a64" + +RDEPENDS_${PN} += "\ + ${PYTHON_PN}-sqlparse \ +" From 15ac010fc9421b0bd48a8884c34d2790e8099b8e Mon Sep 17 00:00:00 2001 From: Leon Anavi Date: Wed, 21 Apr 2021 10:58:43 +0300 Subject: [PATCH 2/5] python3-huey: Upgrade 2.3.1 -> 2.3.2 Upgrade to release 2.3.2: - Add hook (Huey.build_error_result) for customizing the error result metadata. - Avoid crashing if another module already modified/set the multiprocessing start method. Signed-off-by: Leon Anavi Signed-off-by: Khem Raj Signed-off-by: Trevor Gamblin --- .../python/{python3-huey_2.3.1.bb => python3-huey_2.3.2.bb} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename meta-python/recipes-devtools/python/{python3-huey_2.3.1.bb => python3-huey_2.3.2.bb} (70%) diff --git a/meta-python/recipes-devtools/python/python3-huey_2.3.1.bb b/meta-python/recipes-devtools/python/python3-huey_2.3.2.bb similarity index 70% rename from meta-python/recipes-devtools/python/python3-huey_2.3.1.bb rename to meta-python/recipes-devtools/python/python3-huey_2.3.2.bb index d8141c8e813..4ef80c4a855 100644 --- a/meta-python/recipes-devtools/python/python3-huey_2.3.1.bb +++ b/meta-python/recipes-devtools/python/python3-huey_2.3.2.bb @@ -5,7 +5,7 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=5cac039fcc82f01141cc170b48f315d4" PYPI_PACKAGE = "huey" -SRC_URI[sha256sum] = "de9b6d0fd59794378fe05813d302be68038044ef3b68274b84ca8d285e20f803" +SRC_URI[sha256sum] = "7176acb113850824490da5a31f328cc48a2002a59bfb396efbab8ecbd3573910" inherit pypi setuptools3 From 46523d09d9af2f81dfebed82f1893a67b54fcef0 Mon Sep 17 00:00:00 2001 From: Leon Anavi Date: Wed, 21 Apr 2021 10:58:42 +0300 Subject: [PATCH 3/5] python3-pysonos: Upgrade 0.0.42 -> 0.0.43 Upgrade to release 0.0.43: - Downgrade asyncio log severity Signed-off-by: Leon Anavi Signed-off-by: Khem Raj Signed-off-by: Trevor Gamblin --- .../{python3-pysonos_0.0.42.bb => python3-pysonos_0.0.43.bb} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename meta-python/recipes-devtools/python/{python3-pysonos_0.0.42.bb => python3-pysonos_0.0.43.bb} (79%) diff --git a/meta-python/recipes-devtools/python/python3-pysonos_0.0.42.bb b/meta-python/recipes-devtools/python/python3-pysonos_0.0.43.bb similarity index 79% rename from meta-python/recipes-devtools/python/python3-pysonos_0.0.42.bb rename to meta-python/recipes-devtools/python/python3-pysonos_0.0.43.bb index 25defabc51b..dbb6a8d8f6d 100644 --- a/meta-python/recipes-devtools/python/python3-pysonos_0.0.42.bb +++ b/meta-python/recipes-devtools/python/python3-pysonos_0.0.43.bb @@ -4,7 +4,7 @@ SECTION = "devel/python" LICENSE = "MIT" LIC_FILES_CHKSUM = "file://LICENSE.rst;md5=07b0e2ca9ac77cd65cd4edf2e13367ea" -SRC_URI[sha256sum] = "20b45fa1779a01325e67822d243e1a3f7657d8b515308d84c1eb3c805cc3bdb5" +SRC_URI[sha256sum] = "47be2b37defc856f15d7e7a419cfb939e9822750efe968db192156ebeba31684" inherit pypi setuptools3 From fe7c5f4d49a165c558202e02aa2609c87a42e333 Mon Sep 17 00:00:00 2001 From: Leon Anavi Date: Wed, 21 Apr 2021 10:58:41 +0300 Subject: [PATCH 4/5] python3-asttokens: Upgrade 2.0.4 -> 2.0.5 Upgrade to release 2.0.5: - setup.cfg: remove wheel dependency - Handle starred expressions in tests - Make 3.9 support official - pypy2 instead of pypy2.7 - pypy3 instead of pypy3.5 Signed-off-by: Leon Anavi Signed-off-by: Khem Raj Signed-off-by: Trevor Gamblin --- .../{python3-asttokens_2.0.4.bb => python3-asttokens_2.0.5.bb} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename meta-python/recipes-devtools/python/{python3-asttokens_2.0.4.bb => python3-asttokens_2.0.5.bb} (81%) diff --git a/meta-python/recipes-devtools/python/python3-asttokens_2.0.4.bb b/meta-python/recipes-devtools/python/python3-asttokens_2.0.5.bb similarity index 81% rename from meta-python/recipes-devtools/python/python3-asttokens_2.0.4.bb rename to meta-python/recipes-devtools/python/python3-asttokens_2.0.5.bb index c2149336fda..429a56bae60 100644 --- a/meta-python/recipes-devtools/python/python3-asttokens_2.0.4.bb +++ b/meta-python/recipes-devtools/python/python3-asttokens_2.0.5.bb @@ -7,7 +7,7 @@ PYPI_PACKAGE = "asttokens" inherit pypi setuptools3 -SRC_URI[sha256sum] = "a42e57e28f2ac1c85ed9b1f84109401427e5c63c04f61d15b8842b027eec5128" +SRC_URI[sha256sum] = "9a54c114f02c7a9480d56550932546a3f1fe71d8a02f1bc7ccd0ee3ee35cf4d5" DEPENDS += "\ python3-setuptools-scm-native \ From 58939bf7d094a741bc3ac1f5797cac023767bd62 Mon Sep 17 00:00:00 2001 From: Leon Anavi Date: Wed, 21 Apr 2021 10:58:39 +0300 Subject: [PATCH 5/5] python3-hyperframe: Upgrade 6.0.0 -> 6.0.1 Upgrade to release 6.0.1 with the following API changes: - Added support for Python 3.9 - Added type hints Signed-off-by: Leon Anavi Signed-off-by: Khem Raj Signed-off-by: Trevor Gamblin --- ...python3-hyperframe_6.0.0.bb => python3-hyperframe_6.0.1.bb} | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) rename meta-python/recipes-connectivity/python-hyperframe/{python3-hyperframe_6.0.0.bb => python3-hyperframe_6.0.1.bb} (61%) diff --git a/meta-python/recipes-connectivity/python-hyperframe/python3-hyperframe_6.0.0.bb b/meta-python/recipes-connectivity/python-hyperframe/python3-hyperframe_6.0.1.bb similarity index 61% rename from meta-python/recipes-connectivity/python-hyperframe/python3-hyperframe_6.0.0.bb rename to meta-python/recipes-connectivity/python-hyperframe/python3-hyperframe_6.0.1.bb index 4a936b49af5..2d46e961124 100644 --- a/meta-python/recipes-connectivity/python-hyperframe/python3-hyperframe_6.0.0.bb +++ b/meta-python/recipes-connectivity/python-hyperframe/python3-hyperframe_6.0.1.bb @@ -4,7 +4,6 @@ LICENSE = "MIT" LIC_FILES_CHKSUM = "file://LICENSE;md5=5bf1c68e73fbaec2b1687b7e71514393" -SRC_URI[md5sum] = "30136a712e092b1a45ae3cad3ae93131" -SRC_URI[sha256sum] = "742d2a4bc3152a340a49d59f32e33ec420aa8e7054c1444ef5c7efff255842f1" +SRC_URI[sha256sum] = "ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914" inherit pypi setuptools3