forked from pool/python-h2
Compare commits
3 Commits
| Author | SHA256 | Date | |
|---|---|---|---|
| 1b3ba609f1 | |||
| c307d5cabf | |||
| 2f797339dc |
91
CVE-2025-57804.patch
Normal file
91
CVE-2025-57804.patch
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
From 883ed37be42592b2f0aa0caddab6ca5e3d668fa3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thomas Kriechbaumer <thomas@kriechbaumer.name>
|
||||||
|
Date: Mon, 18 Aug 2025 22:46:12 +0200
|
||||||
|
Subject: [PATCH] reject header names and values containing unpermitted
|
||||||
|
characters `\r`, `\n`, or `\0x00`
|
||||||
|
|
||||||
|
---
|
||||||
|
CHANGELOG.rst | 2 +-
|
||||||
|
src/h2/utilities.py | 25 +++++++++++++++++++++++++
|
||||||
|
tests/test_invalid_headers.py | 8 +++++++-
|
||||||
|
3 files changed, 33 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
Index: h2-4.2.0/src/h2/utilities.py
|
||||||
|
===================================================================
|
||||||
|
--- h2-4.2.0.orig/src/h2/utilities.py
|
||||||
|
+++ h2-4.2.0/src/h2/utilities.py
|
||||||
|
@@ -201,6 +201,9 @@ def validate_headers(headers: Iterable[H
|
||||||
|
# For example, we avoid tuple unpacking in loops because it represents a
|
||||||
|
# fixed cost that we don't want to spend, instead indexing into the header
|
||||||
|
# tuples.
|
||||||
|
+ headers = _reject_illegal_characters(
|
||||||
|
+ headers, hdr_validation_flags,
|
||||||
|
+ )
|
||||||
|
headers = _reject_empty_header_names(
|
||||||
|
headers, hdr_validation_flags,
|
||||||
|
)
|
||||||
|
@@ -225,6 +228,36 @@ def validate_headers(headers: Iterable[H
|
||||||
|
return _check_path_header(headers, hdr_validation_flags)
|
||||||
|
|
||||||
|
|
||||||
|
+def _reject_illegal_characters(headers, hdr_validation_flags):
|
||||||
|
+ """
|
||||||
|
+ Raises a ProtocolError if any header names or values contain illegal characters.
|
||||||
|
+ See RFC 9113, section 8.2.1.
|
||||||
|
+ """
|
||||||
|
+ for header in headers:
|
||||||
|
+ # > A field name MUST NOT contain characters in the ranges 0x00-0x20, 0x41-0x5a,
|
||||||
|
+ # > or 0x7f-0xff (all ranges inclusive).
|
||||||
|
+ for c in header[0]:
|
||||||
|
+ if c <= 0x20 or 0x41 <= c <= 0x5a or 0x7f <= c:
|
||||||
|
+ msg = f"Illegal character '{chr(c)}' in header name: {header[0]!r}"
|
||||||
|
+ raise ProtocolError(msg)
|
||||||
|
+
|
||||||
|
+ # > With the exception of pseudo-header fields (Section 8.3), which have a name
|
||||||
|
+ # > that starts with a single colon, field names MUST NOT include a colon (ASCII
|
||||||
|
+ # > COLON, 0x3a).
|
||||||
|
+ if header[0].find(b":", 1) != -1:
|
||||||
|
+ msg = f"Illegal character ':' in header name: {header[0]!r}"
|
||||||
|
+ raise ProtocolError(msg)
|
||||||
|
+
|
||||||
|
+ # > A field value MUST NOT contain the zero value (ASCII NUL, 0x00), line feed
|
||||||
|
+ # > (ASCII LF, 0x0a), or carriage return (ASCII CR, 0x0d) at any position.
|
||||||
|
+ for c in header[1]:
|
||||||
|
+ if c == 0 or c == 0x0a or c == 0x0d:
|
||||||
|
+ msg = f"Illegal character '{chr(c)}' in header value: {header[1]!r}"
|
||||||
|
+ raise ProtocolError(msg)
|
||||||
|
+
|
||||||
|
+ # Surrounding whitespace is enforced in `_reject_surrounding_whitespace`.
|
||||||
|
+ yield header
|
||||||
|
+
|
||||||
|
|
||||||
|
def _reject_empty_header_names(headers: Iterable[Header],
|
||||||
|
hdr_validation_flags: HeaderValidationFlags) -> Generator[Header, None, None]:
|
||||||
|
Index: h2-4.2.0/tests/test_invalid_headers.py
|
||||||
|
===================================================================
|
||||||
|
--- h2-4.2.0.orig/tests/test_invalid_headers.py
|
||||||
|
+++ h2-4.2.0/tests/test_invalid_headers.py
|
||||||
|
@@ -48,6 +48,14 @@ class TestInvalidFrameSequences:
|
||||||
|
[*base_request_headers, ("name ", "name with trailing space")],
|
||||||
|
[*base_request_headers, ("name", " value with leading space")],
|
||||||
|
[*base_request_headers, ("name", "value with trailing space ")],
|
||||||
|
+ [*base_request_headers, ("illegal:characters", "value")],
|
||||||
|
+ [*base_request_headers, ("illegal-\r-characters", "value")],
|
||||||
|
+ [*base_request_headers, ("illegal-\n-characters", "value")],
|
||||||
|
+ [*base_request_headers, ("illegal-\x00-characters", "value")],
|
||||||
|
+ [*base_request_headers, ("illegal-\x01-characters", "value")],
|
||||||
|
+ [*base_request_headers, ("illegal-characters", "some \r value")],
|
||||||
|
+ [*base_request_headers, ("illegal-characters", "some \n value")],
|
||||||
|
+ [*base_request_headers, ("illegal-characters", "some \x00 value")],
|
||||||
|
[header for header in base_request_headers
|
||||||
|
if header[0] != ":authority"],
|
||||||
|
[(":protocol", "websocket"), *base_request_headers],
|
||||||
|
@@ -665,7 +673,7 @@ class TestFilter:
|
||||||
|
|
||||||
|
def test_inbound_header_name_length_full_frame_decode(self, frame_factory) -> None:
|
||||||
|
f = frame_factory.build_headers_frame([])
|
||||||
|
- f.data = b"\x00\x00\x05\x00\x00\x00\x00\x04"
|
||||||
|
+ f.data = b"\x00\x00\x01\x04"
|
||||||
|
data = f.serialize()
|
||||||
|
|
||||||
|
c = h2.connection.H2Connection(config=h2.config.H2Configuration(client_side=False))
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
From 8952c91606cd014720ccf202a25b5ee1fbed1591 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Robert-Andr=C3=A9=20Mauchin?= <zebob.m@gmail.com>
|
|
||||||
Date: Sun, 3 Jul 2022 12:05:05 +0200
|
|
||||||
Subject: [PATCH] Fix repr() checks for Python 3.11
|
|
||||||
|
|
||||||
In Python 3.11, repr() was modified, this commit fixes the
|
|
||||||
assertions to match the new repr() behavior.
|
|
||||||
|
|
||||||
Fix #1268
|
|
||||||
---
|
|
||||||
test/test_events.py | 62 ++++++++++++++++++++++++++++++++-------------
|
|
||||||
1 file changed, 44 insertions(+), 18 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/test/test_events.py b/test/test_events.py
|
|
||||||
index a6e8d8379..c790fbaa0 100644
|
|
||||||
--- a/test/test_events.py
|
|
||||||
+++ b/test/test_events.py
|
|
||||||
@@ -207,11 +207,18 @@ def test_remotesettingschanged_repr(self):
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
- assert repr(e) == (
|
|
||||||
- "<RemoteSettingsChanged changed_settings:{ChangedSetting("
|
|
||||||
- "setting=SettingCodes.INITIAL_WINDOW_SIZE, original_value=65536, "
|
|
||||||
- "new_value=32768)}>"
|
|
||||||
- )
|
|
||||||
+ if sys.version_info >= (3, 11):
|
|
||||||
+ assert repr(e) == (
|
|
||||||
+ "<RemoteSettingsChanged changed_settings:{ChangedSetting("
|
|
||||||
+ "setting=4, original_value=65536, "
|
|
||||||
+ "new_value=32768)}>"
|
|
||||||
+ )
|
|
||||||
+ else:
|
|
||||||
+ assert repr(e) == (
|
|
||||||
+ "<RemoteSettingsChanged changed_settings:{ChangedSetting("
|
|
||||||
+ "setting=SettingCodes.INITIAL_WINDOW_SIZE, original_value=65536, "
|
|
||||||
+ "new_value=32768)}>"
|
|
||||||
+ )
|
|
||||||
|
|
||||||
def test_pingreceived_repr(self):
|
|
||||||
"""
|
|
||||||
@@ -249,10 +256,16 @@ def test_streamreset_repr(self):
|
|
||||||
e.error_code = h2.errors.ErrorCodes.ENHANCE_YOUR_CALM
|
|
||||||
e.remote_reset = False
|
|
||||||
|
|
||||||
- assert repr(e) == (
|
|
||||||
- "<StreamReset stream_id:919, "
|
|
||||||
- "error_code:ErrorCodes.ENHANCE_YOUR_CALM, remote_reset:False>"
|
|
||||||
- )
|
|
||||||
+ if sys.version_info >= (3, 11):
|
|
||||||
+ assert repr(e) == (
|
|
||||||
+ "<StreamReset stream_id:919, "
|
|
||||||
+ "error_code:11, remote_reset:False>"
|
|
||||||
+ )
|
|
||||||
+ else:
|
|
||||||
+ assert repr(e) == (
|
|
||||||
+ "<StreamReset stream_id:919, "
|
|
||||||
+ "error_code:ErrorCodes.ENHANCE_YOUR_CALM, remote_reset:False>"
|
|
||||||
+ )
|
|
||||||
|
|
||||||
def test_pushedstreamreceived_repr(self):
|
|
||||||
"""
|
|
||||||
@@ -284,11 +297,18 @@ def test_settingsacknowledged_repr(self):
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
- assert repr(e) == (
|
|
||||||
- "<SettingsAcknowledged changed_settings:{ChangedSetting("
|
|
||||||
- "setting=SettingCodes.INITIAL_WINDOW_SIZE, original_value=65536, "
|
|
||||||
- "new_value=32768)}>"
|
|
||||||
- )
|
|
||||||
+ if sys.version_info >= (3, 11):
|
|
||||||
+ assert repr(e) == (
|
|
||||||
+ "<SettingsAcknowledged changed_settings:{ChangedSetting("
|
|
||||||
+ "setting=4, original_value=65536, "
|
|
||||||
+ "new_value=32768)}>"
|
|
||||||
+ )
|
|
||||||
+ else:
|
|
||||||
+ assert repr(e) == (
|
|
||||||
+ "<SettingsAcknowledged changed_settings:{ChangedSetting("
|
|
||||||
+ "setting=SettingCodes.INITIAL_WINDOW_SIZE, original_value=65536, "
|
|
||||||
+ "new_value=32768)}>"
|
|
||||||
+ )
|
|
||||||
|
|
||||||
def test_priorityupdated_repr(self):
|
|
||||||
"""
|
|
||||||
@@ -318,10 +338,16 @@ def test_connectionterminated_repr(self, additional_data, data_repr):
|
|
||||||
e.last_stream_id = 33
|
|
||||||
e.additional_data = additional_data
|
|
||||||
|
|
||||||
- assert repr(e) == (
|
|
||||||
- "<ConnectionTerminated error_code:ErrorCodes.INADEQUATE_SECURITY, "
|
|
||||||
- "last_stream_id:33, additional_data:%s>" % data_repr
|
|
||||||
- )
|
|
||||||
+ if sys.version_info >= (3, 11):
|
|
||||||
+ assert repr(e) == (
|
|
||||||
+ "<ConnectionTerminated error_code:12, "
|
|
||||||
+ "last_stream_id:33, additional_data:%s>" % data_repr
|
|
||||||
+ )
|
|
||||||
+ else:
|
|
||||||
+ assert repr(e) == (
|
|
||||||
+ "<ConnectionTerminated error_code:ErrorCodes.INADEQUATE_SECURITY, "
|
|
||||||
+ "last_stream_id:33, additional_data:%s>" % data_repr
|
|
||||||
+ )
|
|
||||||
|
|
||||||
def test_alternativeserviceavailable_repr(self):
|
|
||||||
"""
|
|
||||||
BIN
h2-4.1.0.tar.gz
LFS
BIN
h2-4.1.0.tar.gz
LFS
Binary file not shown.
BIN
h2-4.2.0.tar.gz
LFS
Normal file
BIN
h2-4.2.0.tar.gz
LFS
Normal file
Binary file not shown.
@@ -1,3 +1,31 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Mon Sep 1 12:46:44 UTC 2025 - Nico Krapp <nico.krapp@suse.com>
|
||||||
|
|
||||||
|
- Add CVE-2025-57804.patch to fix CVE-2025-57804 (bsc#1248737)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Tue Feb 11 09:03:44 UTC 2025 - John Paul Adrian Glaubitz <adrian.glaubitz@suse.com>
|
||||||
|
|
||||||
|
- Update to 4.2.0
|
||||||
|
* Support for Python 3.6 has been removed.
|
||||||
|
* Support for Python 3.7 has been removed.
|
||||||
|
* Support for Python 3.8 has been removed.
|
||||||
|
* Remove mistakenly set `max_inbound_frame_size` attribute on `H2Stream`.
|
||||||
|
* Support for Python 3.11 has been added.
|
||||||
|
* Support for Python 3.12 has been added.
|
||||||
|
* Support for Python 3.13 has been added.
|
||||||
|
* Add an ability to send outbound cookies separately to improve headers compression.
|
||||||
|
* Updated packaging and testing infrastructure.
|
||||||
|
* Fix repr() checks for Python 3.11
|
||||||
|
* Fix asyncio / wsgi examples.
|
||||||
|
* Clarify docs on using curl with http2.
|
||||||
|
- Adjust path for patching tests/conftest.py
|
||||||
|
- Drop fix-repr-checks-for-py311.patch, merged upstream
|
||||||
|
- Switch build system from setuptools to pyproject.toml
|
||||||
|
* Add python-pip and python-wheel to BuildRequires
|
||||||
|
* Replace %python_build with %pyproject_wheel
|
||||||
|
* Replace %python_install with %pyproject_install
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Fri Apr 21 12:26:00 UTC 2023 - Dirk Müller <dmueller@suse.com>
|
Fri Apr 21 12:26:00 UTC 2023 - Dirk Müller <dmueller@suse.com>
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# spec file for package python-h2
|
# spec file for package python-h2
|
||||||
#
|
#
|
||||||
# Copyright (c) 2023 SUSE LLC
|
# Copyright (c) 2025 SUSE LLC
|
||||||
#
|
#
|
||||||
# All modifications and additions to the file contributed by third parties
|
# All modifications and additions to the file contributed by third parties
|
||||||
# remain the property of their copyright owners, unless otherwise agreed
|
# remain the property of their copyright owners, unless otherwise agreed
|
||||||
@@ -16,22 +16,24 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
%{?!python_module:%define python_module() python3-%{**}}
|
|
||||||
%define skip_python2 1
|
|
||||||
%{?sle15_python_module_pythons}
|
%{?sle15_python_module_pythons}
|
||||||
Name: python-h2
|
Name: python-h2
|
||||||
Version: 4.1.0
|
Version: 4.2.0
|
||||||
Release: 0
|
Release: 0
|
||||||
Summary: HTTP/2 State-Machine based protocol implementation
|
Summary: HTTP/2 State-Machine based protocol implementation
|
||||||
License: MIT
|
License: MIT
|
||||||
URL: https://github.com/python-hyper/hyper-h2
|
URL: https://github.com/python-hyper/hyper-h2
|
||||||
Source0: https://files.pythonhosted.org/packages/source/h/h2/h2-%{version}.tar.gz
|
Source0: https://files.pythonhosted.org/packages/source/h/h2/h2-%{version}.tar.gz
|
||||||
# Taken from https://github.com/python-hyper/h2/pull/1274
|
# PATCH-FIX-UPSTREAM CVE-2025-57804.patch (bsc#1248737)
|
||||||
Patch1: fix-repr-checks-for-py311.patch
|
# taken from https://github.com/python-hyper/h2/commit/883ed37be42592b2f0aa0caddab6ca5e3d668fa3
|
||||||
|
# and https://github.com/python-hyper/h2/commit/035e9899f95e3709af098f578bfc3cd302298e3a
|
||||||
|
Patch0: CVE-2025-57804.patch
|
||||||
BuildRequires: %{python_module hpack >= 2.3}
|
BuildRequires: %{python_module hpack >= 2.3}
|
||||||
BuildRequires: %{python_module hyperframe >= 6.0}
|
BuildRequires: %{python_module hyperframe >= 6.0}
|
||||||
BuildRequires: %{python_module hypothesis >= 5.49}
|
BuildRequires: %{python_module hypothesis >= 5.49}
|
||||||
|
BuildRequires: %{python_module pip}
|
||||||
BuildRequires: %{python_module pytest}
|
BuildRequires: %{python_module pytest}
|
||||||
|
BuildRequires: %{python_module wheel}
|
||||||
BuildRequires: fdupes
|
BuildRequires: fdupes
|
||||||
BuildRequires: python-rpm-macros
|
BuildRequires: python-rpm-macros
|
||||||
Requires: python-hpack >= 2.3
|
Requires: python-hpack >= 2.3
|
||||||
@@ -56,13 +58,13 @@ hypothesis.settings.register_profile(
|
|||||||
deadline=5000,
|
deadline=5000,
|
||||||
suppress_health_check=[hypothesis.HealthCheck.too_slow]
|
suppress_health_check=[hypothesis.HealthCheck.too_slow]
|
||||||
)
|
)
|
||||||
" >> test/conftest.py
|
" >> tests/conftest.py
|
||||||
|
|
||||||
%build
|
%build
|
||||||
%python_build
|
%pyproject_wheel
|
||||||
|
|
||||||
%install
|
%install
|
||||||
%python_install
|
%pyproject_install
|
||||||
%python_expand %fdupes %{buildroot}%{$python_sitelib}
|
%python_expand %fdupes %{buildroot}%{$python_sitelib}
|
||||||
|
|
||||||
%check
|
%check
|
||||||
|
|||||||
Reference in New Issue
Block a user