From b37ae761bfda975ac5bc378615555a4e647adc04 Mon Sep 17 00:00:00 2001 From: liweigang Date: Mon, 13 Oct 2025 11:07:56 +0800 Subject: [PATCH] fix CVE-2025-59420 and CVE-2025-61920 --- backport-CVE-2025-59420.patch | 117 ++++++++++++++++++++++++++++++++++ backport-CVE-2025-61920.patch | 61 ++++++++++++++++++ python-Authlib.spec | 9 ++- 3 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 backport-CVE-2025-59420.patch create mode 100644 backport-CVE-2025-61920.patch diff --git a/backport-CVE-2025-59420.patch b/backport-CVE-2025-59420.patch new file mode 100644 index 0000000..3c5eb77 --- /dev/null +++ b/backport-CVE-2025-59420.patch @@ -0,0 +1,117 @@ +From 890dc4aafe8fb888e52e58c498fba1449adc064b Mon Sep 17 00:00:00 2001 +From: Super User +Date: Mon, 13 Oct 2025 10:25:35 +0800 +Subject: [PATCH 1/2] fix(jose): validate crit header parameters + +link: https://github.com/authlib/authlib/commit/6b1813e4392eb7c168c276099ff7783b176479df +--- + authlib/jose/errors.py | 7 +++++++ + authlib/jose/rfc7515/jws.py | 39 ++++++++++++++++++++++++++++++++++++- + 2 files changed, 45 insertions(+), 1 deletion(-) + +diff --git a/authlib/jose/errors.py b/authlib/jose/errors.py +index fb02eb4..5198af8 100644 +--- a/authlib/jose/errors.py ++++ b/authlib/jose/errors.py +@@ -33,6 +33,13 @@ class InvalidHeaderParameterNameError(JoseError): + super().__init__( + description=description) + ++class InvalidCritHeaderParameterNameError(JoseError): ++ error = "invalid_crit_header_parameter_name" ++ ++ def __init__(self, name): ++ description = f"Invalid Header Parameter Name: {name}" ++ super().__init__(description=description) ++ + + class InvalidEncryptionAlgorithmForECDH1PUWithKeyWrappingError(JoseError): + error = 'invalid_encryption_algorithm_for_ECDH_1PU_with_key_wrapping' +diff --git a/authlib/jose/rfc7515/jws.py b/authlib/jose/rfc7515/jws.py +index cf19c4b..80ef69b 100644 +--- a/authlib/jose/rfc7515/jws.py ++++ b/authlib/jose/rfc7515/jws.py +@@ -10,6 +10,7 @@ from authlib.jose.util import ( + ) + from authlib.jose.errors import ( + DecodeError, ++ InvalidCritHeaderParameterNameError, + MissingAlgorithmError, + UnsupportedAlgorithmError, + BadSignatureError, +@@ -59,6 +60,7 @@ class JsonWebSignature: + """ + jws_header = JWSHeader(protected, None) + self._validate_private_headers(protected) ++ self._validate_crit_headers(protected) + algorithm, key = self._prepare_algorithm_key(protected, payload, key) + + protected_segment = json_b64encode(jws_header.protected) +@@ -90,6 +92,7 @@ class JsonWebSignature: + raise DecodeError('Not enough segments') + + protected = _extract_header(protected_segment) ++ self._validate_crit_headers(protected) + jws_header = JWSHeader(protected, None) + + payload = _extract_payload(payload_segment) +@@ -127,6 +130,11 @@ class JsonWebSignature: + + def _sign(jws_header): + self._validate_private_headers(jws_header) ++ # RFC 7515 §4.1.11: 'crit' MUST be integrity-protected. ++ # Reject if present in unprotected header, and validate only ++ # against the protected header parameters. ++ self._reject_unprotected_crit(jws_header.header) ++ self._validate_crit_headers(jws_header.protected) + _alg, _key = self._prepare_algorithm_key(jws_header, payload, key) + + protected_segment = json_b64encode(jws_header.protected) +@@ -268,6 +276,28 @@ class JsonWebSignature: + if k not in names: + raise InvalidHeaderParameterNameError(k) + ++ def _reject_unprotected_crit(self, unprotected_header): ++ """Reject 'crit' when found in the unprotected header (RFC 7515 §4.1.11).""" ++ if unprotected_header and "crit" in unprotected_header: ++ raise InvalidHeaderParameterNameError("crit") ++ ++ def _validate_crit_headers(self, header): ++ if "crit" in header: ++ crit_headers = header["crit"] ++ # Type enforcement for robustness and predictable errors ++ if not isinstance(crit_headers, list) or not all( ++ isinstance(x, str) for x in crit_headers ++ ): ++ raise InvalidHeaderParameterNameError("crit") ++ names = self.REGISTERED_HEADER_PARAMETER_NAMES.copy() ++ if self._private_headers: ++ names = names.union(self._private_headers) ++ for k in crit_headers: ++ if k not in names: ++ raise InvalidCritHeaderParameterNameError(k) ++ elif k not in header: ++ raise InvalidCritHeaderParameterNameError(k) ++ + def _validate_json_jws(self, payload_segment, payload, header_obj, key): + protected_segment = header_obj.get('protected') + if not protected_segment: +@@ -282,7 +312,14 @@ class JsonWebSignature: + header = header_obj.get('header') + if header and not isinstance(header, dict): + raise DecodeError('Invalid "header" value') +- ++ # RFC 7515 §4.1.11: 'crit' MUST be integrity-protected. If present in ++ # the unprotected header object, reject the JWS. ++ self._reject_unprotected_crit(header) ++ ++ # Enforce must-understand semantics for names listed in protected ++ # 'crit'. This will also ensure each listed name is present in the ++ # protected header. ++ self._validate_crit_headers(protected) + jws_header = JWSHeader(protected, header) + algorithm, key = self._prepare_algorithm_key(jws_header, payload, key) + signing_input = b'.'.join([protected_segment, payload_segment]) +-- +2.50.1 + diff --git a/backport-CVE-2025-61920.patch b/backport-CVE-2025-61920.patch new file mode 100644 index 0000000..dbdf8ea --- /dev/null +++ b/backport-CVE-2025-61920.patch @@ -0,0 +1,61 @@ +From 33974c7e1d7b26a73c4297b0395ce8c93b3de7e6 Mon Sep 17 00:00:00 2001 +From: Super User +Date: Mon, 13 Oct 2025 10:53:21 +0800 +Subject: [PATCH 2/2] fix(jose): add size limitation to prevent DoS + +link: https://github.com/authlib/authlib/commit/867e3f87b072347a1ae9cf6983cc8bbf88447e5e +--- + authlib/jose/rfc7515/jws.py | 5 +++++ + authlib/jose/util.py | 6 ++++++ + 2 files changed, 11 insertions(+) + +diff --git a/authlib/jose/rfc7515/jws.py b/authlib/jose/rfc7515/jws.py +index 80ef69b..a75e420 100644 +--- a/authlib/jose/rfc7515/jws.py ++++ b/authlib/jose/rfc7515/jws.py +@@ -28,6 +28,8 @@ class JsonWebSignature: + 'typ', 'cty', 'crit' + ]) + ++ MAX_CONTENT_LENGTH: int = 256000 ++ + #: Defined available JWS algorithms in the registry + ALGORITHMS_REGISTRY = {} + +@@ -84,6 +86,9 @@ class JsonWebSignature: + + .. _`Section 7.1`: https://tools.ietf.org/html/rfc7515#section-7.1 + """ ++ if len(s) > self.MAX_CONTENT_LENGTH: ++ raise ValueError("Serialization is too long.") ++ + try: + s = to_bytes(s) + signing_input, signature_segment = s.rsplit(b'.', 1) +diff --git a/authlib/jose/util.py b/authlib/jose/util.py +index 5b0c759..b95c3db 100644 +--- a/authlib/jose/util.py ++++ b/authlib/jose/util.py +@@ -4,6 +4,9 @@ from authlib.jose.errors import DecodeError + + + def extract_header(header_segment, error_cls): ++ if len(header_segment) > 256000: ++ raise ValueError("Value of header is too long") ++ + header_data = extract_segment(header_segment, error_cls, 'header') + + try: +@@ -17,6 +20,9 @@ def extract_header(header_segment, error_cls): + + + def extract_segment(segment, error_cls, name='payload'): ++ if len(segment) > 256000: ++ raise ValueError(f"Value of {name} is too long") ++ + try: + return urlsafe_b64decode(segment) + except (TypeError, binascii.Error): +-- +2.50.1 + diff --git a/python-Authlib.spec b/python-Authlib.spec index d57d020..42b9830 100644 --- a/python-Authlib.spec +++ b/python-Authlib.spec @@ -1,7 +1,7 @@ %global _empty_manifest_terminate_build 0 Name: python-Authlib Version: 1.3.0 -Release: 1 +Release: 2 Summary: The ultimate Python library in building OAuth and OpenID Connect servers and clients. License: BSD 3-Clause License URL: https://authlib.org/ @@ -9,6 +9,10 @@ Source0: https://files.pythonhosted.org/packages/source/A/Authlib/Authlib-1.3.0. BuildArch: noarch Patch0001: backport-fix-prevent-OctKey-to-import-ssh-rsa-pem-keys.patch +# https://github.com/authlib/authlib/commit/6b1813e4392eb7c168c276099ff7783b176479df +Patch0002: backport-CVE-2025-59420.patch +# https://github.com/authlib/authlib/commit/867e3f87b072347a1ae9cf6983cc8bbf88447e5e +Patch0003: backport-CVE-2025-61920.patch Requires: python3-cryptography @@ -74,6 +78,9 @@ mv %{buildroot}/doclist.lst . %{_docdir}/* %changelog +* Mon Oct 13 2025 liweigang - 1.3.0-2 +- fix CVE-2025-59420 and CVE-2025-61920 + * Fri Feb 28 2025 gongzhengtang - 1.3.0-1 - update to v1.3.0 -- Gitee