From 7e21093d1b76a2fa710714f88d776b19391b8e5c Mon Sep 17 00:00:00 2001 From: suresh-thelkar Date: Thu, 14 Nov 2024 21:18:30 +0530 Subject: [PATCH] Patch CVE-2024-49767 in python-werkzeug (#10948) Co-authored-by: Suresh Thelkar --- SPECS/python-werkzeug/CVE-2024-49767.patch | 85 ++++++++++++++++++++++ SPECS/python-werkzeug/python-werkzeug.spec | 6 +- 2 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 SPECS/python-werkzeug/CVE-2024-49767.patch diff --git a/SPECS/python-werkzeug/CVE-2024-49767.patch b/SPECS/python-werkzeug/CVE-2024-49767.patch new file mode 100644 index 00000000000..3229e27a176 --- /dev/null +++ b/SPECS/python-werkzeug/CVE-2024-49767.patch @@ -0,0 +1,85 @@ +From f73af277c1be8adfe429eacef2132785557e448f Mon Sep 17 00:00:00 2001 +From: Suresh Thelkar +Date: Tue, 5 Nov 2024 12:24:50 +0530 +Subject: [PATCH] Patch for CVE-2024-49767 + +Upstream patch details are given below. +https://github.com/pallets/werkzeug/commit/50cfeebcb0727e18cc52ffbeb125f4a66551179b#diff-ff3c479edefad986d2fe6fe7ead575a46b086e3bbcf0ccc86d85efc4a4c63c79 +--- + src/werkzeug/formparser.py | 11 +++++++++++ + src/werkzeug/sansio/multipart.py | 2 ++ + tests/test_formparser.py | 12 ++++++++++++ + 3 files changed, 25 insertions(+) + +diff --git a/src/werkzeug/formparser.py b/src/werkzeug/formparser.py +index ba84721..d961bdb 100644 +--- a/src/werkzeug/formparser.py ++++ b/src/werkzeug/formparser.py +@@ -356,6 +356,7 @@ class MultiPartParser: + self, stream: t.IO[bytes], boundary: bytes, content_length: int | None + ) -> tuple[MultiDict[str, str], MultiDict[str, FileStorage]]: + current_part: Field | File ++ field_size: int | None = None + container: t.IO[bytes] | list[bytes] + _write: t.Callable[[bytes], t.Any] + +@@ -374,13 +375,23 @@ class MultiPartParser: + while not isinstance(event, (Epilogue, NeedData)): + if isinstance(event, Field): + current_part = event ++ field_size = 0 + container = [] + _write = container.append + elif isinstance(event, File): + current_part = event ++ field_size = None + container = self.start_file_streaming(event, content_length) + _write = container.write + elif isinstance(event, Data): ++ if self.max_form_memory_size is not None and field_size is not None: ++ # Ensure that accumulated data events do not exceed limit. ++ # Also checked within single event in MultipartDecoder. ++ field_size += len(event.data) ++ ++ if field_size > self.max_form_memory_size: ++ raise RequestEntityTooLarge() ++ + _write(event.data) + if not event.more_data: + if isinstance(current_part, Field): +diff --git a/src/werkzeug/sansio/multipart.py b/src/werkzeug/sansio/multipart.py +index fc87353..731be03 100644 +--- a/src/werkzeug/sansio/multipart.py ++++ b/src/werkzeug/sansio/multipart.py +@@ -140,6 +140,8 @@ class MultipartDecoder: + self.max_form_memory_size is not None + and len(self.buffer) + len(data) > self.max_form_memory_size + ): ++ # Ensure that data within single event does not exceed limit. ++ # Also checked across accumulated events in MultiPartParser. + raise RequestEntityTooLarge() + else: + self.buffer.extend(data) +diff --git a/tests/test_formparser.py b/tests/test_formparser.py +index 1ecb012..0fe152a 100644 +--- a/tests/test_formparser.py ++++ b/tests/test_formparser.py +@@ -448,3 +448,15 @@ class TestMultiPartParser: + ) as request: + assert request.files["rfc2231"].filename == "a b c d e f.txt" + assert request.files["rfc2231"].read() == b"file contents" ++ ++ ++def test_multipart_max_form_memory_size() -> None: ++ """max_form_memory_size is tracked across multiple data events.""" ++ data = b"--bound\r\nContent-Disposition: form-field; name=a\r\n\r\n" ++ data += b"a" * 15 + b"\r\n--bound--" ++ # The buffer size is less than the max size, so multiple data events will be ++ # returned. The field size is greater than the max. ++ parser = formparser.MultiPartParser(max_form_memory_size=10, buffer_size=5) ++ ++ with pytest.raises(RequestEntityTooLarge): ++ parser.parse(io.BytesIO(data), b"bound", None) +-- +2.34.1 + diff --git a/SPECS/python-werkzeug/python-werkzeug.spec b/SPECS/python-werkzeug/python-werkzeug.spec index 6b960e277e7..bd767f3fb0d 100644 --- a/SPECS/python-werkzeug/python-werkzeug.spec +++ b/SPECS/python-werkzeug/python-werkzeug.spec @@ -4,7 +4,7 @@ Summary: The Swiss Army knife of Python web development Name: python-werkzeug Version: 3.0.3 -Release: 1%{?dist} +Release: 2%{?dist} License: BSD Vendor: Microsoft Corporation Distribution: Azure Linux @@ -14,6 +14,7 @@ Source0: https://github.com/pallets/werkzeug/archive/%{version}.tar.gz#/w # Fixes PYTHONPATH handling in tests # Upstream: https://github.com/pallets/werkzeug/pull/2172 Patch0: preserve-any-existing-PYTHONPATH-in-tests.patch +Patch1: CVE-2024-49767.patch BuildArch: noarch %description @@ -78,6 +79,9 @@ pip3 install markupsafe %files -n python3-werkzeug-doc %changelog +* Tue Nov 05 2024 Suresh Thelkar - 3.0.3-2 +- Patch CVE-2024-49767 + * Thu May 30 2024 Neha Agarwal - 3.0.3-1 - Update to version 3.0.3 to fix CVE-2024-34069.