Open
fix(cve): 修复 CVE-2026-103001 在 python-jwt 中的漏洞, CVE-2026-102275, CVE-2026-102267, CVE-2026-101917, CVE-2026-102271, CVE-2026-102269, CVE-2026-102265, CVE-2026-102273, CVE-2026-102272 #98
fix(cve): 修复 CVE-2026-103001 在 python-jwt 中的漏洞, CVE-2026-102275, CVE-2026-102267, CVE-2026-101917, CVE-2026-102271, CVE-2026-102269, CVE-2026-102265, CVE-2026-102273, CVE-2026-102272 #98
Open
infra_teamAdd on 29 days ago
Total: 5 files changed+9-165
@@ -1,51 +0,0 @@
1-From f91ed44dd65baaf457f4b3353ed35e98a753934c Mon Sep 17 00:00:00 2001
2-From: =?UTF-8?q?Jos=C3=A9=20Padilla?= <jpadilla@users.noreply.github.com>
3-Date: Wed, 9 Sep 2026 16:29:06 -0400
4-Subject: [PATCH] Validate PyJWK HMAC keys consistently
5- 
6-Reference: https://github.com/jpadilla/pyjwt/commit/f91ed44dd65baaf457f4b3353ed35e98a753934c.patch
7-Conflict: NA
8- 
9----
10- jwt/api_jws.py | 2 +-
11- tests/test_api_jws.py | 17 +++++++++++++++++
12- 2 files changed, 18 insertions(+), 1 deletion(-)
13- 
14-diff --git a/jwt/api_jws.py b/jwt/api_jws.py
15-index d0ae3fcc..81a2ccb4 100644
16---- a/jwt/api_jws.py
17-+++ b/jwt/api_jws.py
18-@@ -414,7 +414,7 @@ def _verify_signature(
19- f"algorithm {key.algorithm_name!r}"
20- )
21- alg_obj = key.Algorithm
22-- prepared_key = key.key
23-+ prepared_key = alg_obj.prepare_key(key.key)
24- else:
25- try:
26- alg_obj = self.get_algorithm_by_name(alg)
27-diff --git a/tests/test_api_jws.py b/tests/test_api_jws.py
28-index 2f5f7fc1..1eb5a8fc 100644
29---- a/tests/test_api_jws.py
30-+++ b/tests/test_api_jws.py
31-@@ -1264,3 +1264,20 @@ def test_get_unverified_header_rejects_unknown_crit(
32-
33- with pytest.raises(InvalidTokenError, match="Unsupported critical extension"):
34- jws.get_unverified_header(token)
35-+ def test_decode_rejects_empty_hmac_pyjwk(self) -> None:
36-+ import base64
37-+ import hashlib
38-+ import hmac
39-+ import jwt
40-+
41-+ jwk = jwt.PyJWK.from_dict(
42-+ {"kty": "oct", "k": "", "kid": "active", "alg": "HS256"}
43-+ )
44-+ signing_input = b"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhdHRhY2tlciJ9"
45-+ signature = hmac.new(b"", signing_input, hashlib.sha256).digest()
46-+ token = (
47-+ signing_input + b"." + base64.urlsafe_b64encode(signature).rstrip(b"=")
48-+ ).decode()
49-+
50-+ with pytest.raises(jwt.InvalidKeyError, match="must not be empty"):
51-+ jwt.decode(token, jwk, algorithms=["HS256"])
@@ -1,109 +0,0 @@
1-From 8b4e233a22206b34ec1186e912e75c0b2396ac07 Mon Sep 17 00:00:00 2001
2-From: =?UTF-8?q?Jos=C3=A9=20Padilla?= <jpadilla@users.noreply.github.com>
3-Date: Wed, 9 Sep 2026 21:49:21 -0400
4-Subject: [PATCH] fix: reject loader-accepted PEM variants
5- 
6-Reference: https://github.com/jpadilla/pyjwt/commit/8b4e233a22206b34ec1186e912e75c0b2396ac07.patch
7-Conflict: NA
8- 
9----
10- jwt/utils.py | 20 ++++++++++--------
11- tests/test_algorithms.py | 44 +++++++++++++++++++++++++++++++++++++++-
12- 2 files changed, 55 insertions(+), 9 deletions(-)
13- 
14-diff --git a/jwt/utils.py b/jwt/utils.py
15-index 56e89bb7..914cb50d 100644
16---- a/jwt/utils.py
17-+++ b/jwt/utils.py
18-@@ -113,18 +113,22 @@ def raw_to_der_signature(raw_sig: bytes, curve: "EllipticCurve") -> bytes:
19- b"X509 CRL",
20- }
21-
22--_PEM_RE = re.compile(
23-- b"----[- ]BEGIN ("
24-- + b"|".join(_PEMS)
25-- + b""")[- ]----\r?
26--.+?\r?
27------[- ]END \\1[- ]----\r?\n?""",
28-- re.DOTALL,
29-+# Accept PEM formatting variants that the cryptography loader accepts, while
30-+# retaining the explicit asymmetric-key marker check.
31-+_PEM_MARKER_RE = re.compile(
32-+ b"(?=(----[- ](BEGIN|END) (" + b"|".join(_PEMS) + b")[- ]----))"
33- )
34-
35-
36- def is_pem_format(key: bytes) -> bool:
37-- return bool(_PEM_RE.search(key))
38-+ begin_markers: dict[bytes, int] = {}
39-+ for marker in _PEM_MARKER_RE.finditer(key):
40-+ marker_type, label = marker.group(2), marker.group(3)
41-+ if marker_type == b"BEGIN":
42-+ begin_markers[label] = marker.start(1) + len(marker.group(1))
43-+ elif label in begin_markers and begin_markers[label] < marker.start(1):
44-+ return True
45-+ return False
46-
47-
48- # Based on https://github.com/pyca/cryptography/blob/bcb70852d577b3f490f015378c75cba74986297b/src/cryptography/hazmat/primitives/serialization/ssh.py#L40-L46
49-diff --git a/tests/test_algorithms.py b/tests/test_algorithms.py
50-index c854f723..3d85a0cd 100644
51---- a/tests/test_algorithms.py
52-+++ b/tests/test_algorithms.py
53-@@ -1,6 +1,6 @@
54- import base64
55- import json
56--from typing import Union, cast
57-+from typing import Callable, Union, cast
58-
59- import pytest
60-
61-@@ -89,6 +89,48 @@ def test_hmac_should_throw_exception(self, key: str) -> None:
62- with open(key_path(key)) as keyfile:
63- algo.prepare_key(keyfile.read())
64-
65-+ @pytest.mark.parametrize(
66-+ "mutation",
67-+ [
68-+ lambda key: key.replace(b"-----END", b"\t-----END"),
69-+ lambda key: key.replace(b"\n", b"\r"),
70-+ lambda key: key.replace(b"\n", b""),
71-+ ],
72-+ )
73-+ def test_hmac_should_reject_loader_accepted_pem_mutations(
74-+ self, mutation: Callable[[bytes], bytes]
75-+ ) -> None:
76-+ algo = HMACAlgorithm(HMACAlgorithm.SHA256)
77-+ with open(key_path("testkey2_rsa.pub.pem"), "rb") as keyfile:
78-+ mutated_key = mutation(keyfile.read())
79-+
80-+ with pytest.raises(InvalidKeyError):
81-+ algo.prepare_key(mutated_key)
82-+
83-+ def test_hmac_should_accept_incomplete_pem_marker(self) -> None:
84-+ algo = HMACAlgorithm(HMACAlgorithm.SHA256)
85-+ key = b"-----BEGIN PUBLIC KEY-----" * 10000
86-+
87-+ assert algo.prepare_key(key) == key
88-+
89-+ def test_hmac_should_reject_a_later_pem_block(self) -> None:
90-+ algo = HMACAlgorithm(HMACAlgorithm.SHA256)
91-+ with open(key_path("testkey2_rsa.pub.pem"), "rb") as keyfile:
92-+ key = b"-----BEGIN PUBLIC KEY-----" + keyfile.read()
93-+
94-+ with pytest.raises(InvalidKeyError):
95-+ algo.prepare_key(key)
96-+
97-+ def test_hmac_should_reject_a_pem_block_after_an_overlapping_end_marker(
98-+ self,
99-+ ) -> None:
100-+ algo = HMACAlgorithm(HMACAlgorithm.SHA256)
101-+ with open(key_path("testkey2_rsa.pub.pem"), "rb") as keyfile:
102-+ key = b"-----END CERTIFICATE" + keyfile.read()
103-+
104-+ with pytest.raises(InvalidKeyError):
105-+ algo.prepare_key(key)
106-+
107- def test_hmac_jwk_should_parse_and_verify(self) -> None:
108- algo = HMACAlgorithm(HMACAlgorithm.SHA256)
109-
Binary files do not support preview
Binary files do not support preview
@@ -1,14 +1,12 @@
1%global srcname jwt1%global srcname jwt
2%bcond_without tests2%bcond_without tests
3Name: python-jwt3Name: python-jwt
4-Version: 2.13.04+Version: 2.15.0
5-Release: 35+Release: 4
6Summary: JSON Web Token implementation in Python6Summary: JSON Web Token implementation in Python
7License: MIT7License: MIT
8URL: https://github.com/jpadilla/pyjwt8URL: https://github.com/jpadilla/pyjwt
9Source0: https://files.pythonhosted.org/packages/source/p/pyjwt/pyjwt-%{version}.tar.gz9Source0: https://files.pythonhosted.org/packages/source/p/pyjwt/pyjwt-%{version}.tar.gz
10-Patch6000: backport-CVE-2026-102268.patch
11-Patch6001: backport-CVE-2026-102266.patch
12BuildArch: noarch10BuildArch: noarch
13 11 
14BuildRequires: python3-devel12BuildRequires: python3-devel
@@ -43,7 +41,7 @@ from setuptools import setup, find_packages
43 41 
44setup(42setup(
45 name='PyJWT',43 name='PyJWT',
46- version='2.13.0',44+ version='2.15.0',
47 description='JSON Web Token implementation in Python',45 description='JSON Web Token implementation in Python',
48 url='https://github.com/jpadilla/pyjwt',46 url='https://github.com/jpadilla/pyjwt',
49 packages=find_packages(exclude=['tests', 'tests.*']),47 packages=find_packages(exclude=['tests', 'tests.*']),
@@ -79,6 +77,12 @@ rm -f tests/test_jwks_client.py
79%doc README.rst77%doc README.rst
80 78 
81%changelog79%changelog
80+* Sat Oct 10 2026 infra_team <zhaiwenjie1@huawei.com> - 2.15.0-4
81+- Type:CVE
82+- CVE:CVE-2026-103001
83+- SUG:NA
84+- DESC:update to 2.15.0, fix CVE-2026-103001
85+ 
82* Fri Oct 09 2026 yixiangzhike <yixiangzhike007@163.com> - 2.13.0-386* Fri Oct 09 2026 yixiangzhike <yixiangzhike007@163.com> - 2.13.0-3
83- Type:CVE87- Type:CVE
84- CVE:CVE-2026-10226688- CVE:CVE-2026-102266