diff mbox series

[meta-python,scarthgap,4/5] python3-pyjwt: Fix CVE-2026-48526

Message ID 20260806055101.23160-4-hthakar@cisco.com
State New
Headers show
Series [meta-python,scarthgap,1/5] python3-pyjwt: Fix CVE-2026-48522 | expand

Commit Message

From: Hetvi Thakar <hthakar@cisco.com>

Reject JSON Web Key documents passed directly as HMAC secrets. This
prevents public asymmetric JWK data from being reused as an HMAC key
when an application permits mixed symmetric and asymmetric algorithms.

This patch applies the relevant subset of the upstream 2.13.0 fix.
The upstream commit is referenced in [1], and the public advisory is
referenced in [2].

[1] https://github.com/jpadilla/pyjwt/commit/95791b1759b8aa4f2203575d344d5c78564cdc81
[2] https://github.com/advisories/GHSA-xgmm-8j9v-c9wx

Signed-off-by: Hetvi Thakar <hthakar@cisco.com>
---
 .../python/python3-pyjwt/CVE-2026-48526.patch | 87 +++++++++++++++++++
 .../python/python3-pyjwt_2.8.0.bb             |  1 +
 2 files changed, 88 insertions(+)
 create mode 100644 meta-python/recipes-devtools/python/python3-pyjwt/CVE-2026-48526.patch
diff mbox series

Patch

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?= <jpadilla@users.noreply.github.com>
+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 <hthakar@cisco.com>
+---
+ 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"