已开启
[openEuler-20.03-LTS-SP4] backport: Fix decompression-bomb safeguards bypass in streaming API (CVE-2026-9375) #198
刘德华海淀分华创建于 6月21日
[openEuler-20.03-LTS-SP4] backport: Fix decompression-bomb safeguards bypass in streaming API (CVE-2026-9375) #198
已开启
共 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.25.9 | 5 | Version: 1.25.9 |
| 6 | -Release: 17 | 6 | +Release: 18 |
| 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 |
| @@ -31,6 +31,7 @@ Patch6015: backport-0004-CVE-2025-66471.patch | |||
| 31 | Patch6016: backport-CVE-2026-21441.patch | 31 | Patch6016: backport-CVE-2026-21441.patch |
| 32 | Patch6017: backport-Prevent-issue-in-HTTPResponse-.read-when-decoded_con.patch | 32 | Patch6017: backport-Prevent-issue-in-HTTPResponse-.read-when-decoded_con.patch |
| 33 | Patch6018: backport-CVE-2026-44431.patch | 33 | Patch6018: backport-CVE-2026-44431.patch |
| 34 | +Patch6019: backport-CVE-2026-9375.patch | ||
| 34 | 35 | ||
| 35 | %global _description \ | 36 | %global _description \ |
| 36 | HTTP library with thread-safe connection pooling, file post support,\ | 37 | HTTP library with thread-safe connection pooling, file post support,\ |
| @@ -132,6 +133,12 @@ PYTHONPATH=%{buildroot}%{python3_sitelib}:%{python3_sitelib} %{__python3} -m pyt | |||
| 132 | %{python3_sitelib}/urllib3-*.egg-info | 133 | %{python3_sitelib}/urllib3-*.egg-info |
| 133 | 134 | ||
| 134 | %changelog | 135 | %changelog |
| 136 | +* Sun Jun 21 2026 andy-lau <liuyang01@kylinos.cn> - 1.25.9-18 | ||
| 137 | +- Type:CVE | ||
| 138 | +- CVE:CVE-2026-9375 | ||
| 139 | +- SUG:NA | ||
| 140 | +- DESC:fix CVE-2026-9375, fix decompression-bomb safeguards bypass in streaming API | ||
| 141 | + | ||
| 135 | * Wed May 13 2026 tangce <tangce1@h-partners.com> - 1.25.9-17 | 142 | * Wed May 13 2026 tangce <tangce1@h-partners.com> - 1.25.9-17 |
| 136 | - Type:CVE | 143 | - Type:CVE |
| 137 | - CVE:CVE-2026-44431 | 144 | - CVE:CVE-2026-44431 |