diff --git a/meta-python/recipes-devtools/python/python3-pyjwt/CVE-2026-48526.patch b/meta-python/recipes-devtools/python/python3-pyjwt/CVE-2026-48526.patch new file mode 100644 index 0000000000..6cde3ccce3 --- /dev/null +++ b/meta-python/recipes-devtools/python/python3-pyjwt/CVE-2026-48526.patch @@ -0,0 +1,87 @@ +From 9d2064bccc0ac60884906d9dd89ace589f9f8281 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jos=C3=A9=20Padilla?= +Date: Mon, 3 Aug 2026 03:22:08 -0700 +Subject: [PATCH] algorithms: reject raw JWK documents as HMAC secrets + +Reject JSON Web Key documents passed directly to +HMACAlgorithm.prepare_key. Public asymmetric JWK data must not be +accepted as an HMAC secret when callers permit mixed algorithm families. + +CVE: CVE-2026-48526 +Upstream-Status: Backport [https://github.com/jpadilla/pyjwt/commit/95791b1759b8aa4f2203575d344d5c78564cdc81] + +Backport Changes: +- Extracted only the CVE-2026-48526 raw-JWK rejection and regression tests + from the bundled upstream 2.13.0 commit. The other requested CVE fixes + are carried as separate patches. +- Adapted the hunk and test locations to PyJWT 2.8.0, renamed the upstream + local variable `jwk_obj` to `jwk`, and omitted explanatory comments; + the validation logic and assertions are unchanged. +- Excluded the separate empty-HMAC-key hardening bundled in the same file. +- Omitted the 2.13.0 version and changelog updates, CVE-2026-48523 (which + does not affect 2.8.0), and unrelated hardening from the bundled commit. + +(cherry picked from commit 95791b1759b8aa4f2203575d344d5c78564cdc81) +Signed-off-by: Hetvi Thakar +--- + jwt/algorithms.py | 13 +++++++++++++ + tests/test_algorithms.py | 22 ++++++++++++++++++++++ + 2 files changed, 35 insertions(+) + +diff --git a/jwt/algorithms.py b/jwt/algorithms.py +index ed18715..b6303ed 100644 +--- a/jwt/algorithms.py ++++ b/jwt/algorithms.py +@@ -270,6 +270,19 @@ class HMACAlgorithm(Algorithm): + " should not be used as an HMAC secret." + ) + ++ stripped = key_bytes.lstrip() ++ if stripped.startswith(b"{"): ++ try: ++ jwk = json.loads(key_bytes) ++ except ValueError: ++ jwk = None ++ if isinstance(jwk, dict) and "kty" in jwk: ++ raise InvalidKeyError( ++ "The specified key looks like a JWK and should not be " ++ "used directly as an HMAC secret. Load it via " ++ "PyJWK / HMACAlgorithm.from_jwk first." ++ ) ++ + return key_bytes + + @overload +diff --git a/tests/test_algorithms.py b/tests/test_algorithms.py +index 1a39552..e5220c6 100644 +--- a/tests/test_algorithms.py ++++ b/tests/test_algorithms.py +@@ -108,6 +108,28 @@ class TestAlgorithms: + with pytest.raises(InvalidKeyError): + algo.from_jwk(keyfile.read()) + ++ @pytest.mark.parametrize( ++ "jwk_file", ++ [ ++ "jwk_rsa_pub.json", ++ "jwk_ec_pub_P-256.json", ++ "jwk_okp_pub_Ed25519.json", ++ "jwk_hmac.json", ++ ], ++ ) ++ def test_hmac_prepare_key_rejects_jwk_json(self, jwk_file: str) -> None: ++ algo = HMACAlgorithm(HMACAlgorithm.SHA256) ++ ++ with open(key_path(jwk_file)) as keyfile: ++ with pytest.raises(InvalidKeyError, match="looks like a JWK"): ++ algo.prepare_key(keyfile.read()) ++ ++ def test_hmac_prepare_key_accepts_json_without_kty(self) -> None: ++ algo = HMACAlgorithm(HMACAlgorithm.SHA256) ++ ++ key = algo.prepare_key('{"this": "is just a json-shaped secret"}') ++ assert key == b'{"this": "is just a json-shaped secret"}' ++ + @crypto_required + def test_rsa_should_parse_pem_public_key(self): + algo = RSAAlgorithm(RSAAlgorithm.SHA256) diff --git a/meta-python/recipes-devtools/python/python3-pyjwt_2.8.0.bb b/meta-python/recipes-devtools/python/python3-pyjwt_2.8.0.bb index fc3e0bc31d..3804d8ab72 100644 --- a/meta-python/recipes-devtools/python/python3-pyjwt_2.8.0.bb +++ b/meta-python/recipes-devtools/python/python3-pyjwt_2.8.0.bb @@ -10,6 +10,7 @@ SRC_URI += " \ file://CVE-2026-48522.patch \ file://CVE-2026-48524.patch \ file://CVE-2026-48525.patch \ + file://CVE-2026-48526.patch \ " SRC_URI[sha256sum] = "57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de"