已开启
[openEuler-24.03-LTS-SP4] backport: Fix decompression-bomb safeguards bypass in streaming API (CVE-2026-9375) #196
刘德华海淀分华创建于 6月21日
[openEuler-24.03-LTS-SP4] backport: Fix decompression-bomb safeguards bypass in streaming API (CVE-2026-9375) #196
已开启
共 2 个文件变更+88-1
| @@ -0,0 +1,80 @@ | |||
| 1 | +From 2bdcc44d1e163fb5cc48a8662425e35e15adfe6a Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: Illia Volochii <illia.volochii@gmail.com> | ||
| 3 | +Date: Thu, 7 May 2026 18:39:03 +0300 | ||
| 4 | +Subject: [PATCH] Merge commit from fork | ||
| 5 | + | ||
| 6 | +* Avoid any decoding in `HTTPResponse.drain_conn` | ||
| 7 | + | ||
| 8 | +* Add a comment | ||
| 9 | + | ||
| 10 | +* Simplify `drain_conn` | ||
| 11 | + | ||
| 12 | +* Add tests | ||
| 13 | + | ||
| 14 | +* Add additional checks to the test | ||
| 15 | + | ||
| 16 | +* Fix full decompression on the 2nd small read from response using Brotli | ||
| 17 | + | ||
| 18 | +* Add a changelog entry | ||
| 19 | + | ||
| 20 | +* Inverse the order in the changelog entry | ||
| 21 | + | ||
| 22 | +* Mention `stream` call | ||
| 23 | +--- | ||
| 24 | + changelog/GHSA-mf9v-mfxr-j63j.bugfix.rst | 7 +++++++ | ||
| 25 | + src/urllib3/response.py | 17 +++++++++++------ | ||
| 26 | + test/test_response.py | 24 +++++++++++++++++++++--- | ||
| 27 | + test/with_dummyserver/test_connection.py | 19 +++++++++++++++++++ | ||
| 28 | + 4 files changed, 58 insertions(+), 9 deletions(-) | ||
| 29 | + create mode 100644 changelog/GHSA-mf9v-mfxr-j63j.bugfix.rst | ||
| 30 | + | ||
| 31 | +diff --git a/changelog/GHSA-mf9v-mfxr-j63j.bugfix.rst b/changelog/GHSA-mf9v-mfxr-j63j.bugfix.rst | ||
| 32 | +new file mode 100644 | ||
| 33 | +index 0000000000..ac70af825a | ||
| 34 | +--- /dev/null | ||
| 35 | ++++ b/changelog/GHSA-mf9v-mfxr-j63j.bugfix.rst | ||
| 36 | + | ||
| 37 | ++Fixed two high-severity security issues where decompression-bomb safeguards of the streaming API were bypassed: | ||
| 38 | ++ | ||
| 39 | ++ | ||
| 40 | ++1. When ``HTTPResponse.drain_conn()`` was called after the response had been read and decompressed partially. | ||
| 41 | ++2. During the second ``HTTPResponse.read(amt=N)`` or ``HTTPResponse.stream(amt=N)`` call when the response was decompressed using the official `Brotli <https://pypi.org/project/brotli/>`__ library. | ||
| 42 | ++ | ||
| 43 | ++See `GHSA-mf9v-mfxr-j63j <https://github.com/urllib3/urllib3/security/advisories/GHSA-mf9v-mfxr-j63j>`__ for details. | ||
| 44 | +diff --git a/src/urllib3/response.py b/src/urllib3/response.py | ||
| 45 | +index 521c31b282..e9246b75e3 100644 | ||
| 46 | +--- a/src/urllib3/response.py | ||
| 47 | ++++ b/src/urllib3/response.py | ||
| 48 | + def drain_conn(self): | ||
| 49 | + Unread data in the HTTPResponse connection blocks the connection from being released back to the pool. | ||
| 50 | + """ | ||
| 51 | + try: | ||
| 52 | +- self.read( | ||
| 53 | +- # Do not spend resources decoding the content unless | ||
| 54 | +- # decoding has already been initiated. | ||
| 55 | +- decode_content=self._has_decoded_content, | ||
| 56 | +- ) | ||
| 57 | ++ self._raw_read() | ||
| 58 | + except (HTTPError, SocketError, BaseSSLError, HTTPException): | ||
| 59 | + pass | ||
| 60 | ++ if self._has_decoded_content: | ||
| 61 | ++ # `_raw_read` skips decompression, so we should clean up the | ||
| 62 | ++ # decoder to avoid keeping unnecessary data in memory. | ||
| 63 | ++ self._decoded_buffer = BytesQueueBuffer() | ||
| 64 | ++ self._decoder = None | ||
| 65 | + | ||
| 66 | + @property | ||
| 67 | + def data(self): | ||
| 68 | + def read( | ||
| 69 | + if amt is not None: | ||
| 70 | + cache_content = False | ||
| 71 | + | ||
| 72 | +- if self._decoder and self._decoder.has_unconsumed_tail: | ||
| 73 | ++ if ( | ||
| 74 | ++ self._decoder | ||
| 75 | ++ and self._decoder.has_unconsumed_tail | ||
| 76 | ++ and len(self._decoded_buffer) < amt | ||
| 77 | ++ ): | ||
| 78 | + decoded_data = self._decode( | ||
| 79 | + b"", | ||
| 80 | + decode_content, | ||
| @@ -3,7 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | Name: python-%{srcname} | 4 | Name: python-%{srcname} |
| 5 | Version: 1.26.18 | 5 | Version: 1.26.18 |
| 6 | -Release: 8 | 6 | +Release: 9 |
| 7 | Summary: Sanity-friendly HTTP client for Python | 7 | Summary: Sanity-friendly HTTP client for Python |
| 8 | License: MIT | 8 | License: MIT |
| 9 | URL: https://urllib3.readthedocs.io | 9 | URL: https://urllib3.readthedocs.io |
| @@ -21,6 +21,7 @@ Patch6005: backport-CVE-2025-66471-3.patch | |||
| 21 | Patch6006: backport-CVE-2026-21441.patch | 21 | Patch6006: backport-CVE-2026-21441.patch |
| 22 | Patch6007: backport-Prevent-issue-in-HTTPResponse-.read-when-decoded_con.patch | 22 | Patch6007: backport-Prevent-issue-in-HTTPResponse-.read-when-decoded_con.patch |
| 23 | Patch6008: backport-CVE-2026-44431.patch | 23 | Patch6008: backport-CVE-2026-44431.patch |
| 24 | +Patch6009: backport-CVE-2026-9375.patch | ||
| 24 | 25 | ||
| 25 | BuildArch: noarch | 26 | BuildArch: noarch |
| 26 | 27 | ||
| @@ -86,6 +87,12 @@ PYTHONPATH=%{buildroot}%{python3_sitelib}:%{python3_sitelib} %{__python3} -m pyt | |||
| 86 | %{python3_sitelib}/urllib3-*.egg-info | 87 | %{python3_sitelib}/urllib3-*.egg-info |
| 87 | 88 | ||
| 88 | %changelog | 89 | %changelog |
| 90 | +* Sun Jun 21 2026 andy-lau <liuyang01@kylinos.cn> - 1.26.18-9 | ||
| 91 | +- Type:CVE | ||
| 92 | +- CVE:CVE-2026-9375 | ||
| 93 | +- SUG:NA | ||
| 94 | +- DESC:fix CVE-2026-9375, fix decompression-bomb safeguards bypass in streaming API | ||
| 95 | + | ||
| 89 | * Tue May 12 2026 tangce <tangce1@h-partners.com> - 1.26.18-8 | 96 | * Tue May 12 2026 tangce <tangce1@h-partners.com> - 1.26.18-8 |
| 90 | - Type:CVE | 97 | - Type:CVE |
| 91 | - CVE:CVE-2026-44431 | 98 | - CVE:CVE-2026-44431 |